KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > debugger > jpda > JPDASupport


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.api.debugger.jpda;
21
22 import java.net.MalformedURLException JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Map JavaDoc;
25 import org.netbeans.api.debugger.*;
26
27 import java.io.*;
28 import java.util.*;
29 import java.net.URLClassLoader JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.beans.PropertyChangeEvent JavaDoc;
32 import java.text.DateFormat JavaDoc;
33 import java.text.SimpleDateFormat JavaDoc;
34
35 import com.sun.jdi.connect.*;
36 import com.sun.jdi.VirtualMachineManager;
37 import com.sun.jdi.Bootstrap;
38 //import org.netbeans.api.java.classpath.ClassPath;
39
//import org.netbeans.spi.java.classpath.support.ClassPathSupport;
40

41 /**
42  * Contains support functionality for unit tests.
43  *
44  * @author Maros Sandor
45  */

46 public class JPDASupport implements DebuggerManagerListener {
47
48     private static final boolean verbose = false;
49     private static final DateFormat JavaDoc df = new SimpleDateFormat JavaDoc("kk:mm:ss.SSS");
50     private static DebuggerManager dm = DebuggerManager.getDebuggerManager ();
51
52     private JPDADebugger jpdaDebugger;
53     private DebuggerEngine debuggerEngine;
54     
55
56     private Object JavaDoc [] debuggerStartLock = new Object JavaDoc[1];
57     private Object JavaDoc [] stepLock = new Object JavaDoc[1];
58
59     private Object JavaDoc STATE_LOCK = new Object JavaDoc ();
60     
61     
62     private JPDASupport (JPDADebugger jpdaDebugger) {
63         this.jpdaDebugger = jpdaDebugger;
64         jpdaDebugger.addPropertyChangeListener (this);
65         DebuggerEngine[] de = dm.getDebuggerEngines ();
66         int i, k = de.length;
67         for (i = 0; i < k; i++)
68             if (de [i].lookupFirst (null, JPDADebugger.class) == jpdaDebugger) {
69                 debuggerEngine = de [i];
70                 break;
71             }
72     }
73
74     
75     // starting methods ........................................................
76

77 // public static JPDASupport listen (String mainClass)
78
// throws IOException, IllegalConnectorArgumentsException,
79
// DebuggerStartException {
80
// VirtualMachineManager vmm = Bootstrap.virtualMachineManager ();
81
// List lconnectors = vmm.listeningConnectors ();
82
// ListeningConnector connector = null;
83
// for (Iterator i = lconnectors.iterator (); i.hasNext ();) {
84
// ListeningConnector lc = (ListeningConnector) i.next ();
85
// Transport t = lc.transport ();
86
// if (t != null && t.name ().equals ("dt_socket")) {
87
// connector = lc;
88
// break;
89
// }
90
// }
91
// if (connector == null)
92
// throw new RuntimeException
93
// ("No listening socket connector available");
94
//
95
// Map args = connector.defaultArguments ();
96
// String address = connector.startListening (args);
97
// String localhostAddres;
98
// try
99
// {
100
// int port = Integer.parseInt
101
// (address.substring (address.indexOf (':') + 1));
102
// localhostAddres = "localhost:" + port;
103
// Connector.IntegerArgument portArg =
104
// (Connector.IntegerArgument) args.get("port");
105
// portArg.setValue(port);
106
// } catch (Exception e) {
107
// // this address format is not known, use default
108
// localhostAddres = address;
109
// }
110
//
111
// JPDADebugger jpdaDebugger = JPDADebugger.listen
112
// (connector, args, createServices ());
113
// if (jpdaDebugger == null)
114
// throw new DebuggerStartException ("JPDA jpdaDebugger was not started");
115
// Process process = launchVM (mainClass, localhostAddres, false);
116
// ProcessIO pio = new ProcessIO (process);
117
// pio.go ();
118
// return new JPDASupport (jpdaDebugger);
119
// }
120

121     public static JPDASupport attach (String JavaDoc mainClass) throws IOException,
122     DebuggerStartException {
123         Process JavaDoc process = launchVM (mainClass, "", true);
124         String JavaDoc line = readLine (process.getInputStream ());
125         int port = Integer.parseInt (line.substring (line.lastIndexOf (':') + 1).trim ());
126         ProcessIO pio = new ProcessIO (process);
127         pio.go ();
128
129         VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
130         List aconnectors = vmm.attachingConnectors();
131         AttachingConnector connector = null;
132         for (Iterator i = aconnectors.iterator(); i.hasNext();) {
133             AttachingConnector ac = (AttachingConnector) i.next();
134             Transport t = ac.transport ();
135             if (t != null && t.name().equals("dt_socket")) {
136                 connector = ac;
137                 break;
138             }
139         }
140         if (connector == null)
141             throw new RuntimeException JavaDoc
142                 ("No attaching socket connector available");
143
144         JPDADebugger jpdaDebugger = JPDADebugger.attach (
145             "localhost",
146             port,
147             createServices ()
148         );
149         return new JPDASupport (jpdaDebugger);
150     }
151
152     
153     // public interface ........................................................
154

155     public void doContinue () {
156         if (jpdaDebugger.getState () != JPDADebugger.STATE_STOPPED)
157             throw new IllegalStateException JavaDoc ();
158         debuggerEngine.getActionsManager ().doAction
159             (ActionsManager.ACTION_CONTINUE);
160     }
161
162     public void stepOver () {
163         step (ActionsManager.ACTION_STEP_OVER);
164     }
165
166     public void stepInto () {
167         step (ActionsManager.ACTION_STEP_INTO);
168     }
169
170     public void stepOut () {
171         step (ActionsManager.ACTION_STEP_OUT);
172     }
173
174     public void step (Object JavaDoc action) {
175         if (jpdaDebugger.getState () != JPDADebugger.STATE_STOPPED)
176             throw new IllegalStateException JavaDoc ();
177         debuggerEngine.getActionsManager ().doAction (action);
178         waitState (JPDADebugger.STATE_STOPPED);
179     }
180
181     public void stepAsynch (final Object JavaDoc actionAsynch, final ActionsManagerListener al) {
182         if (jpdaDebugger.getState () != JPDADebugger.STATE_STOPPED)
183             throw new IllegalStateException JavaDoc ();
184         debuggerEngine.getActionsManager().addActionsManagerListener(
185                 new ActionsManagerListener() {
186                     public void actionPerformed(Object JavaDoc action) {
187                         if (action != actionAsynch) return ;
188                         al.actionPerformed(action);
189                         debuggerEngine.getActionsManager().removeActionsManagerListener(this);
190                     }
191                     public void actionStateChanged(Object JavaDoc action, boolean enabled) {
192                     }
193                 }
194         );
195         debuggerEngine.getActionsManager ().postAction (actionAsynch);
196     }
197
198     public void doFinish () {
199         if (jpdaDebugger == null) return;
200         debuggerEngine.getActionsManager ().
201             doAction (ActionsManager.ACTION_KILL);
202         waitState (JPDADebugger.STATE_DISCONNECTED);
203     }
204
205     public void waitState (int state) {
206         synchronized (STATE_LOCK) {
207             while ( jpdaDebugger.getState () != state &&
208                     jpdaDebugger.getState () != JPDADebugger.STATE_DISCONNECTED
209             ) {
210                 try {
211                     STATE_LOCK.wait ();
212                 } catch (InterruptedException JavaDoc ex) {
213                     ex.printStackTrace ();
214                 }
215             }
216         }
217     }
218
219     public JPDADebugger getDebugger() {
220         return jpdaDebugger;
221     }
222     
223     public static void removeAllBreakpoints () {
224         Breakpoint[] bs = DebuggerManager.getDebuggerManager ().
225             getBreakpoints ();
226         int i, k = bs.length;
227         for (i = 0; i < k; i++)
228             DebuggerManager.getDebuggerManager ().removeBreakpoint (bs [i]);
229     }
230     
231     
232     // other methods ...........................................................
233

234     private static Object JavaDoc[] createServices () {
235 // try {
236
Map JavaDoc map = new HashMap JavaDoc ();
237 // ClassLoader cl = JPDASupport.class.getClassLoader ();
238
// String file = "org/netbeans/api/debugger/jpda/testapps/LineBreakpointApp.class";
239
// URL url = cl.getResource (file);
240
// String surl = url.toString ();
241
// url = new URL (surl.substring (0, surl.length () - file.length ()));
242
// ClassPath cp = ClassPathSupport.createClassPath (new URL[] {
243
// url
244
// });
245
// map.put ("sourcepath", cp);
246
return new Object JavaDoc[] {
247                 map
248             };
249 // } catch (MalformedURLException ex) {
250
// return new Object[] {};
251
// }
252
}
253
254     private static String JavaDoc readLine (InputStream in) throws IOException {
255         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
256         for (;;) {
257             int c = in.read();
258             if (c == -1) throw new EOFException();
259             if (c == 0x0D) {
260                 c = in.read();
261                 if (c != 0x0A) sb.append((char)0x0D);
262             }
263             if (c == 0x0A) return sb.toString();
264             sb.append((char)c);
265         }
266     }
267     
268     private static Process JavaDoc launchVM (
269         String JavaDoc mainClass,
270         String JavaDoc connectorAddress,
271         boolean server
272     ) throws IOException {
273
274         URLClassLoader JavaDoc ucl = (URLClassLoader JavaDoc) JPDASupport.class.
275             getClassLoader ();
276         URL JavaDoc [] urls = ucl.getURLs ();
277
278         StringBuffer JavaDoc cp = new StringBuffer JavaDoc (200);
279         for (int i = 0; i < urls.length; i++) {
280             URL JavaDoc url = urls [i];
281             cp.append (url.getPath ());
282             cp.append (File.pathSeparatorChar);
283         }
284
285         String JavaDoc [] cmdArray = new String JavaDoc [] {
286             System.getProperty ("java.home") + File.separatorChar +
287                 "bin" + File.separatorChar + "java",
288             "-Xdebug",
289             "-Xnoagent",
290             "-Xrunjdwp:transport=" + "dt_socket" + ",address=" +
291                 connectorAddress + ",suspend=y,server=" +
292                 (server ? "y" : "n"),
293             "-classpath",
294             cp.substring(0, cp.length() -1),
295             mainClass
296         };
297
298         return Runtime.getRuntime ().exec (cmdArray);
299     }
300     
301     public String JavaDoc toString () {
302         switch (jpdaDebugger.getState ()) {
303             case JPDADebugger.STATE_DISCONNECTED:
304                 return "Debugger finished.";
305             case JPDADebugger.STATE_RUNNING:
306                 return "Debugger running.";
307             case JPDADebugger.STATE_STARTING:
308                 return "Debugger starting.";
309             case JPDADebugger.STATE_STOPPED:
310                 CallStackFrame f = jpdaDebugger.getCurrentCallStackFrame ();
311                 return "Debugger stopped: " +
312                     f.getClassName () + "." +
313                     f.getMethodName () + ":" +
314                     f.getLineNumber (null);
315         }
316         return super.toString ();
317     }
318     
319     // DebuggerListener ........................................................
320

321     public Breakpoint[] initBreakpoints() {
322         return new Breakpoint[0];
323     }
324
325     public void breakpointAdded(Breakpoint breakpoint) {
326     }
327
328     public void breakpointRemoved(Breakpoint breakpoint) {
329     }
330
331     public void initWatches() {
332     }
333
334     public void watchAdded(Watch watch) {
335     }
336
337     public void watchRemoved(Watch watch) {
338     }
339
340     public void sessionAdded(Session session) {
341     }
342
343     public void sessionRemoved(Session session) {
344     }
345
346     public void propertyChange (PropertyChangeEvent JavaDoc evt) {
347         if (evt.getSource() instanceof JPDADebugger) {
348             JPDADebugger dbg = (JPDADebugger) evt.getSource();
349
350             if (JPDADebugger.PROP_STATE.equals(evt.getPropertyName())) {
351                 synchronized (STATE_LOCK) {
352                     STATE_LOCK.notifyAll ();
353                 }
354                 if (jpdaDebugger.getState () == JPDADebugger.STATE_DISCONNECTED)
355                     jpdaDebugger.removePropertyChangeListener (this);
356             }
357         }
358     }
359
360     // TODO: Include check of these call in the test suite
361
public void engineAdded (DebuggerEngine debuggerEngine) {
362     }
363
364     // TODO: Include check of these call in the test suite
365
public void engineRemoved (DebuggerEngine debuggerEngine) {
366     }
367
368     
369     // innerclasses ............................................................
370

371     private static class ProcessIO {
372
373         private Process JavaDoc p;
374
375         public ProcessIO(Process JavaDoc p) {
376             this.p = p;
377         }
378
379         public void go() {
380             InputStream out = p.getInputStream();
381             InputStream err = p.getErrorStream();
382
383             new SimplePipe(System.out, out).start();
384             new SimplePipe(System.out, err).start();
385         }
386     }
387
388     private static class SimplePipe extends Thread JavaDoc {
389         private OutputStream out;
390         private InputStream in;
391
392         public SimplePipe(OutputStream out, InputStream in) {
393             this.out = out;
394             this.in = in;
395             setDaemon(true);
396         }
397
398         public void run() {
399             byte [] buffer = new byte[1024];
400             int n;
401             try {
402                 while ((n = in.read(buffer)) != -1) {
403                     out.write(buffer, 0, n);
404                 }
405             } catch (IOException e) {
406             } finally {
407                 try {
408                     out.close();
409                     in.close();
410                 } catch (IOException e) {
411                 }
412             }
413             System.out.println("PIO QUIT");
414         }
415     }
416 }
417
Popular Tags