KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > debugger > jpda > JPDADebuggerImpl


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.debugger.jpda;
21
22 import com.sun.jdi.AbsentInformationException;
23 import com.sun.jdi.Bootstrap;
24 import com.sun.jdi.IncompatibleThreadStateException;
25 import com.sun.jdi.InvalidStackFrameException;
26 import com.sun.jdi.LocalVariable;
27 import com.sun.jdi.Method;
28 import com.sun.jdi.ObjectReference;
29 import com.sun.jdi.ReferenceType;
30 import com.sun.jdi.StackFrame;
31 import com.sun.jdi.ThreadGroupReference;
32 import com.sun.jdi.ThreadReference;
33 import com.sun.jdi.TypeComponent;
34 import com.sun.jdi.VMDisconnectedException;
35 import com.sun.jdi.Value;
36 import com.sun.jdi.VirtualMachine;
37 import com.sun.jdi.request.EventRequest;
38 import com.sun.jdi.request.EventRequestManager;
39 import com.sun.jdi.request.InvalidRequestStateException;
40
41 import java.beans.PropertyChangeEvent JavaDoc;
42 import java.beans.PropertyChangeListener JavaDoc;
43 import java.beans.PropertyChangeSupport JavaDoc;
44 import java.util.ArrayList JavaDoc;
45 import java.util.Arrays JavaDoc;
46 import java.util.Collection JavaDoc;
47 import java.util.Collections JavaDoc;
48 import java.util.HashSet JavaDoc;
49 import java.util.Iterator JavaDoc;
50 import java.util.List JavaDoc;
51 import java.util.Set JavaDoc;
52 import java.lang.reflect.InvocationTargetException JavaDoc;
53 import java.util.HashMap JavaDoc;
54 import java.util.Map JavaDoc;
55 import java.util.logging.Level JavaDoc;
56 import java.util.logging.Logger JavaDoc;
57 import org.netbeans.api.debugger.DebuggerEngine;
58
59 import org.netbeans.api.debugger.DebuggerInfo;
60 import org.netbeans.api.debugger.DebuggerManager;
61 import org.netbeans.api.debugger.LazyActionsManagerListener;
62 import org.netbeans.api.debugger.Properties;
63
64 import org.netbeans.api.debugger.jpda.InvalidExpressionException;
65 import org.netbeans.api.debugger.jpda.JPDAClassType;
66 import org.netbeans.api.debugger.jpda.JPDAThreadGroup;
67 import org.netbeans.modules.debugger.jpda.actions.CompoundSmartSteppingListener;
68 import org.netbeans.modules.debugger.jpda.expr.EvaluationException;
69 import org.netbeans.modules.debugger.jpda.models.ObjectTranslation;
70 import org.netbeans.modules.debugger.jpda.util.JPDAUtils;
71 import org.netbeans.spi.debugger.ContextProvider;
72 import org.netbeans.api.debugger.Session;
73 import org.netbeans.api.debugger.jpda.AbstractDICookie;
74 import org.netbeans.api.debugger.jpda.AttachingDICookie;
75 import org.netbeans.api.debugger.jpda.CallStackFrame;
76 import org.netbeans.api.debugger.jpda.DebuggerStartException;
77 import org.netbeans.api.debugger.jpda.JPDABreakpoint;
78 import org.netbeans.api.debugger.jpda.event.JPDABreakpointEvent;
79 import org.netbeans.api.debugger.jpda.JPDADebugger;
80 import org.netbeans.api.debugger.jpda.JPDAThread;
81 import org.netbeans.api.debugger.jpda.SmartSteppingFilter;
82 import org.netbeans.api.debugger.jpda.Variable;
83 import org.netbeans.api.debugger.jpda.JPDAStep;
84 import org.netbeans.modules.debugger.jpda.breakpoints.BreakpointsEngineListener;
85
86 import org.netbeans.modules.debugger.jpda.models.JPDAThreadImpl;
87 import org.netbeans.modules.debugger.jpda.models.LocalsTreeModel;
88 import org.netbeans.modules.debugger.jpda.models.ThreadsTreeModel;
89 import org.netbeans.modules.debugger.jpda.models.CallStackFrameImpl;
90 import org.netbeans.modules.debugger.jpda.util.Operator;
91 import org.netbeans.modules.debugger.jpda.expr.Expression;
92 import org.netbeans.modules.debugger.jpda.expr.EvaluationContext;
93 import org.netbeans.modules.debugger.jpda.expr.ParseException;
94 import org.netbeans.spi.debugger.DebuggerEngineProvider;
95 import org.netbeans.spi.debugger.DelegatingSessionProvider;
96
97 import org.netbeans.spi.viewmodel.TreeModel;
98 import org.netbeans.spi.viewmodel.UnknownTypeException;
99 import org.openide.ErrorManager;
100
101 /**
102 * Representation of a debugging session.
103 *
104 * @author Jan Jancura
105 */

106 public class JPDADebuggerImpl extends JPDADebugger {
107     
108     private static final Logger JavaDoc logger = Logger.getLogger("org.netbeans.modules.debugger.jpda");
109     
110     private static final boolean SINGLE_THREAD_STEPPING = Boolean.getBoolean("netbeans.debugger.singleThreadStepping");
111
112
113     // variables ...............................................................
114

115     //private DebuggerEngine debuggerEngine;
116
private VirtualMachine virtualMachine = null;
117     private Exception JavaDoc exception;
118     private int state = 0;
119     private Operator operator;
120     private PropertyChangeSupport JavaDoc pcs;
121     private JPDAThreadImpl currentThread;
122     private CallStackFrame currentCallStackFrame;
123     private int suspend = (SINGLE_THREAD_STEPPING) ? SUSPEND_EVENT_THREAD : SUSPEND_ALL;
124     public final Object JavaDoc LOCK = new Object JavaDoc ();
125     private final Object JavaDoc LOCK2 = new Object JavaDoc ();
126     private boolean starting;
127     private JavaEngineProvider javaEngineProvider;
128     private Set JavaDoc<String JavaDoc> languages;
129     private String JavaDoc lastStratumn;
130     private ContextProvider lookupProvider;
131     private ObjectTranslation threadsTranslation;
132     private ObjectTranslation localsTranslation;
133     private ExpressionPool expressionPool;
134
135     private StackFrame altCSF = null; //PATCH 48174
136

137     private boolean doContinue = true; // Whether resume() will actually resume
138

139     // init ....................................................................
140

141     public JPDADebuggerImpl (ContextProvider lookupProvider) {
142         this.lookupProvider = lookupProvider;
143         pcs = new PropertyChangeSupport JavaDoc (this);
144         List JavaDoc l = lookupProvider.lookup (null, DebuggerEngineProvider.class);
145         int i, k = l.size ();
146         for (i = 0; i < k; i++)
147             if (l.get (i) instanceof JavaEngineProvider)
148                 javaEngineProvider = (JavaEngineProvider) l.get (i);
149         if (javaEngineProvider == null)
150             throw new IllegalArgumentException JavaDoc
151                 ("JavaEngineProvider have to be used to start JPDADebugger!");
152         languages = new HashSet JavaDoc<String JavaDoc>();
153         languages.add ("Java");
154         threadsTranslation = ObjectTranslation.createThreadTranslation(this);
155         localsTranslation = ObjectTranslation.createLocalsTranslation(this);
156         this.expressionPool = new ExpressionPool();
157     }
158
159
160     // JPDADebugger methods ....................................................
161

162     /**
163      * Returns current state of JPDA debugger.
164      *
165      * @return current state of JPDA debugger
166      * @see #STATE_STARTING
167      * @see #STATE_RUNNING
168      * @see #STATE_STOPPED
169      * @see #STATE_DISCONNECTED
170      */

171     public int getState () {
172         return state;
173     }
174
175     /**
176      * Gets value of suspend property.
177      *
178      * @return value of suspend property
179      */

180     public int getSuspend () {
181         return suspend;
182     }
183
184     /**
185      * Sets value of suspend property.
186      *
187      * @param s a new value of suspend property
188      */

189     public void setSuspend (int s) {
190         if (s == suspend) return;
191         int old = suspend;
192         suspend = s;
193         firePropertyChange (PROP_SUSPEND, new Integer JavaDoc (old), new Integer JavaDoc (s));
194     }
195
196     /**
197      * Returns current thread or null.
198      *
199      * @return current thread or null
200      */

201     public JPDAThread getCurrentThread () {
202         return currentThread;
203     }
204
205     /**
206      * Returns current stack frame or null.
207      *
208      * @return current stack frame or null
209      */

210     public synchronized CallStackFrame getCurrentCallStackFrame () {
211         if (currentCallStackFrame != null) {
212             try {
213                 if (!currentCallStackFrame.getThread().isSuspended()) {
214                     currentCallStackFrame = null;
215                 }
216             } catch (InvalidStackFrameException isfex) {
217                 currentCallStackFrame = null;
218             }
219         }
220         if (currentCallStackFrame == null && currentThread != null) {
221             try {
222                 currentCallStackFrame = currentThread.getCallStack(0, 1)[0];
223             } catch (Exception JavaDoc ex) {}
224         }
225         return currentCallStackFrame;
226     }
227
228     /**
229      * Evaluates given expression in the current context.
230      *
231      * @param expression a expression to be evaluated
232      *
233      * @return current value of given expression
234      */

235     public Variable evaluate (String JavaDoc expression)
236     throws InvalidExpressionException {
237         Value v = evaluateIn (expression);
238         return getLocalsTreeModel ().getVariable (v);
239     }
240
241     /**
242      * Waits till the Virtual Machine is started and returns
243      * {@link DebuggerStartException} if any.
244      *
245      * @throws DebuggerStartException is some problems occurres during debugger
246      * start
247      *
248      * @see AbstractDICookie#getVirtualMachine()
249      */

250     public void waitRunning () throws DebuggerStartException {
251         synchronized (LOCK2) {
252             if (getState () == STATE_DISCONNECTED) {
253                 if (exception != null)
254                     throw new DebuggerStartException (exception);
255                 else
256                     return;
257             }
258             if (!starting && state != STATE_STARTING || exception != null) {
259                 return ; // We're already running
260
}
261             try {
262                 LOCK2.wait ();
263             } catch (InterruptedException JavaDoc e) {
264                  throw new DebuggerStartException (e);
265             }
266             
267             if (exception != null)
268                 throw new DebuggerStartException (exception);
269             else
270                 return;
271         }
272     }
273
274     /**
275      * Returns <code>true</code> if this debugger supports Pop action.
276      *
277      * @return <code>true</code> if this debugger supports Pop action
278      */

279     public boolean canPopFrames () {
280         VirtualMachine vm = getVirtualMachine ();
281         if (vm == null) return false;
282         return vm.canPopFrames ();
283     }
284
285     /**
286      * Returns <code>true</code> if this debugger supports fix & continue
287      * (HotSwap).
288      *
289      * @return <code>true</code> if this debugger supports fix & continue
290      */

291     public boolean canFixClasses () {
292         VirtualMachine vm = getVirtualMachine ();
293         if (vm == null) return false;
294         return vm.canRedefineClasses ();
295     }
296
297     /**
298      * Implements fix & continue (HotSwap). Map should contain class names
299      * as a keys, and byte[] arrays as a values.
300      *
301      * @param classes a map from class names to be fixed to byte[]
302      */

303     public void fixClasses (Map JavaDoc<String JavaDoc, byte[]> classes) {
304         synchronized (LOCK) {
305             
306             // 1) redefine classes
307
Map JavaDoc<ReferenceType, byte[]> map = new HashMap JavaDoc<ReferenceType, byte[]>();
308             Iterator JavaDoc<String JavaDoc> i = classes.keySet ().iterator ();
309             VirtualMachine vm = getVirtualMachine();
310             if (vm == null) {
311                 return ; // The session has finished
312
}
313             while (i.hasNext ()) {
314                 String JavaDoc className = i.next ();
315                 List JavaDoc<ReferenceType> classRefs = vm.classesByName (className);
316                 int j, jj = classRefs.size ();
317                 for (j = 0; j < jj; j++)
318                     map.put (
319                         classRefs.get (j),
320                         classes.get (className)
321                     );
322             }
323             vm.redefineClasses (map);
324
325             // update breakpoints
326
Session s = (Session)
327                 lookupProvider.lookupFirst (null, Session.class);
328             DebuggerEngine de = s.getEngineForLanguage ("Java");
329             BreakpointsEngineListener bel = null;
330             List JavaDoc lazyListeners = de.lookup(null, LazyActionsManagerListener.class);
331             for (int li = 0; li < lazyListeners.size(); li++) {
332                 Object JavaDoc service = lazyListeners.get(li);
333                 if (service instanceof BreakpointsEngineListener) {
334                     bel = (BreakpointsEngineListener) service;
335                     break;
336                 }
337             }
338             bel.fixBreakpointImpls ();
339             
340             // 2) pop obsoleted frames
341
JPDAThread t = getCurrentThread ();
342             if (t != null && t.isSuspended()) {
343                 CallStackFrame frame = getCurrentCallStackFrame ();
344
345                 //PATCH #52209
346
if (t.getStackDepth () < 2 && frame.isObsolete()) return;
347                 try {
348                     if (!frame.equals (t.getCallStack (0, 1) [0])) return;
349                 } catch (AbsentInformationException ex) {
350                     return;
351                 }
352
353                 //PATCH #52209
354
if (frame.isObsolete () && ((CallStackFrameImpl) frame).canPop()) {
355                     frame.popFrame ();
356                     setState (STATE_RUNNING);
357                     updateCurrentCallStackFrame (t);
358                     setState (STATE_STOPPED);
359                 }
360             }
361             
362         }
363     }
364     
365     private Boolean JavaDoc canBeModified;
366     private Object JavaDoc canBeModifiedLock = new Object JavaDoc();
367     
368     public boolean canBeModified() {
369         VirtualMachine vm = getVirtualMachine ();
370         if (vm == null) return false;
371         synchronized (canBeModifiedLock) {
372             if (canBeModified == null) {
373                 try {
374                     java.lang.reflect.Method JavaDoc canBeModifiedMethod =
375                             com.sun.jdi.VirtualMachine.class.getMethod("canBeModified", new Class JavaDoc[] {});
376                     Object JavaDoc modifiable = canBeModifiedMethod.invoke(vm, new Object JavaDoc[] {});
377                     canBeModified = (Boolean JavaDoc) modifiable;
378                 } catch (NoSuchMethodException JavaDoc nsmex) {
379                     // On JDK 1.4 we do not know... we suppose that can
380
canBeModified = Boolean.TRUE;
381                 } catch (IllegalAccessException JavaDoc iaex) {
382                     canBeModified = Boolean.TRUE;
383                 } catch (InvocationTargetException JavaDoc itex) {
384                     canBeModified = Boolean.TRUE;
385                 }
386             }
387             return canBeModified.booleanValue();
388         }
389         // return vm.canBeModified(); -- After we'll build on JDK 1.5
390
}
391
392     private SmartSteppingFilter smartSteppingFilter;
393
394     /**
395      * Returns instance of SmartSteppingFilter.
396      *
397      * @return instance of SmartSteppingFilter
398      */

399     public SmartSteppingFilter getSmartSteppingFilter () {
400         if (smartSteppingFilter == null) {
401             smartSteppingFilter = (SmartSteppingFilter) lookupProvider.
402                 lookupFirst (null, SmartSteppingFilter.class);
403             smartSteppingFilter.addExclusionPatterns (
404                 (Set JavaDoc) Properties.getDefault ().getProperties ("debugger").
405                     getProperties ("sources").getProperties ("class_filters").
406                     getCollection (
407                         "enabled",
408                         Collections.EMPTY_SET
409                     )
410             );
411         }
412         return smartSteppingFilter;
413     }
414
415     CompoundSmartSteppingListener compoundSmartSteppingListener;
416     
417     private CompoundSmartSteppingListener getCompoundSmartSteppingListener () {
418         if (compoundSmartSteppingListener == null)
419             compoundSmartSteppingListener = (CompoundSmartSteppingListener) lookupProvider.
420                 lookupFirst (null, CompoundSmartSteppingListener.class);
421         return compoundSmartSteppingListener;
422     }
423     
424     /**
425      * Test whether we should stop here according to the smart-stepping rules.
426      */

427     boolean stopHere(JPDAThread t) {
428         return getCompoundSmartSteppingListener ().stopHere
429                      (lookupProvider, t, getSmartSteppingFilter());
430     }
431     
432     /**
433      * Helper method that fires JPDABreakpointEvent on JPDABreakpoints.
434      *
435      * @param breakpoint a breakpoint to be changed
436      * @param event a event to be fired
437      */

438     public void fireBreakpointEvent (
439         JPDABreakpoint breakpoint,
440         JPDABreakpointEvent event
441     ) {
442         super.fireBreakpointEvent (breakpoint, event);
443     }
444
445     /**
446     * Adds property change listener.
447     *
448     * @param l new listener.
449     */

450     public void addPropertyChangeListener (PropertyChangeListener JavaDoc l) {
451         pcs.addPropertyChangeListener (l);
452     }
453
454     /**
455     * Removes property change listener.
456     *
457     * @param l removed listener.
458     */

459     public void removePropertyChangeListener (PropertyChangeListener JavaDoc l) {
460         pcs.removePropertyChangeListener (l);
461     }
462
463     /**
464     * Adds property change listener.
465     *
466     * @param l new listener.
467     */

468     public void addPropertyChangeListener (String JavaDoc propertyName, PropertyChangeListener JavaDoc l) {
469         pcs.addPropertyChangeListener (propertyName, l);
470     }
471
472     /**
473     * Removes property change listener.
474     *
475     * @param l removed listener.
476     */

477     public void removePropertyChangeListener (String JavaDoc propertyName, PropertyChangeListener JavaDoc l) {
478         pcs.removePropertyChangeListener (propertyName, l);
479     }
480
481     
482     // internal interface ......................................................
483

484     public void popFrames (ThreadReference thread, StackFrame frame) {
485         synchronized (LOCK) {
486             JPDAThreadImpl threadImpl = (JPDAThreadImpl) getThread(thread);
487             setState (STATE_RUNNING);
488             try {
489                 threadImpl.popFrames(frame);
490                 updateCurrentCallStackFrame (threadImpl);
491             } catch (IncompatibleThreadStateException ex) {
492                 ErrorManager.getDefault().notify(ex);
493             } finally {
494                 setState (STATE_STOPPED);
495             }
496         }
497     }
498
499     public void setException (Exception JavaDoc e) {
500         synchronized (LOCK2) {
501             exception = e;
502             starting = false;
503             LOCK2.notify ();
504         }
505     }
506
507     public void setCurrentThread (JPDAThread thread) {
508         Object JavaDoc oldT = currentThread;
509         currentThread = (JPDAThreadImpl) thread;
510         if (thread != oldT)
511             pcs.firePropertyChange (PROP_CURRENT_THREAD, oldT, currentThread);
512         updateCurrentCallStackFrame (thread);
513     }
514
515     /**
516      * Set the current thread and call stack, but do not fire changes.
517      * @return The PropertyChangeEvent associated with this change, it can have
518      * attached other PropertyChangeEvents as a propagation ID.
519      */

520     private PropertyChangeEvent JavaDoc setCurrentThreadNoFire(JPDAThread thread) {
521         Object JavaDoc oldT = currentThread;
522         currentThread = (JPDAThreadImpl) thread;
523         PropertyChangeEvent JavaDoc evt = null;
524         if (thread != oldT)
525             evt = new PropertyChangeEvent JavaDoc(this, PROP_CURRENT_THREAD, oldT, currentThread);
526         PropertyChangeEvent JavaDoc evt2 = updateCurrentCallStackFrameNoFire(thread);
527         if (evt == null) evt = evt2;
528         else if (evt2 != null) evt.setPropagationId(evt2);
529         return evt;
530     }
531
532     public void setCurrentCallStackFrame (CallStackFrame callStackFrame) {
533         CallStackFrame old = setCurrentCallStackFrameNoFire(callStackFrame);
534         if (old == callStackFrame) return ;
535         pcs.firePropertyChange (
536             PROP_CURRENT_CALL_STACK_FRAME,
537             old,
538             callStackFrame
539         );
540     }
541     
542     private CallStackFrame setCurrentCallStackFrameNoFire (CallStackFrame callStackFrame) {
543         CallStackFrame old;
544         synchronized (this) {
545             if (callStackFrame == currentCallStackFrame) return callStackFrame;
546             old = currentCallStackFrame;
547             currentCallStackFrame = callStackFrame;
548         }
549         return old;
550     }
551
552     /**
553      * Used by AbstractVariable.
554      */

555     public Value evaluateIn (String JavaDoc expression) throws InvalidExpressionException {
556         Expression expr = null;
557         try {
558             expr = Expression.parse (expression, Expression.LANGUAGE_JAVA_1_5);
559             return evaluateIn (expr);
560         } catch (ParseException e) {
561             InvalidExpressionException iee = new InvalidExpressionException(e.getMessage());
562             iee.initCause(e);
563             throw iee;
564         }
565     }
566     
567     //PATCH 48174
568
public void setAltCSF(StackFrame sf) {
569         altCSF = sf;
570     }
571     
572     public StackFrame getAltCSF() {
573         return altCSF;
574     }
575     
576     /**
577      * Used by WatchesModel & BreakpointImpl.
578      */

579     public Value evaluateIn (Expression expression)
580     throws InvalidExpressionException {
581         synchronized (LOCK) {
582             
583             CallStackFrameImpl csf = (CallStackFrameImpl)
584                 getCurrentCallStackFrame ();
585             if (csf != null) {
586                 JPDAThread frameThread = csf.getThread();
587                 try {
588                     Value value = evaluateIn (expression, csf.getStackFrame ());
589                     try {
590                         csf.getThread();
591                     } catch (InvalidStackFrameException isfex) {
592                         // The frame is invalidated, set the new current...
593
int depth = csf.getFrameDepth();
594                         try {
595                             CallStackFrame csf2 = frameThread.getCallStack(depth, depth + 1)[0];
596                             setCurrentCallStackFrameNoFire(csf2);
597                         } catch (AbsentInformationException aiex) {
598                             setCurrentCallStackFrame(null);
599                         }
600                     }
601                     return value;
602                 } catch (com.sun.jdi.VMDisconnectedException e) {
603                     // Causes kill action when something is being evaluated.
604
return null;
605                 }
606             }
607             //PATCH 48174
608
if (altCSF != null) {
609                 try {
610                     if (!altCSF.thread().isSuspended()) {
611                         altCSF = null; // Already invalid
612
} else {
613                         // TODO XXX : Can be resumed in the mean time !!!!
614
return evaluateIn (expression, altCSF);
615                     }
616                 } catch (InvalidStackFrameException isfex) {
617                     // Will be thrown when the altCSF is invalid
618
altCSF = null; // throw it
619
} catch (com.sun.jdi.VMDisconnectedException e) {
620                     // Causes kill action when something is being evaluated.
621
return null;
622                 }
623             }
624             throw new InvalidExpressionException
625                     ("No current context (stack frame)");
626             
627         }
628     }
629
630     private InvalidExpressionException methodCallsUnsupportedExc;
631
632     /**
633      * Used by BreakpointImpl.
634      */

635     public Value evaluateIn (Expression expression, final StackFrame frame)
636     throws InvalidExpressionException {
637         synchronized (LOCK) {
638             if (frame == null)
639                 throw new InvalidExpressionException ("No current context");
640
641             // TODO: get imports from the source file
642
List JavaDoc<String JavaDoc> imports = new ArrayList JavaDoc<String JavaDoc>();
643             List JavaDoc<String JavaDoc> staticImports = new ArrayList JavaDoc<String JavaDoc>();
644             imports.add ("java.lang.*");
645             try {
646                 imports.addAll (Arrays.asList (EditorContextBridge.getImports (
647                     getEngineContext ().getURL (frame, "Java")
648                 )));
649                 final ThreadReference tr = frame.thread();
650                 final List JavaDoc<EventRequest>[] disabledBreakpoints =
651                         new List JavaDoc[] { null };
652                 final JPDAThreadImpl[] resumedThread = new JPDAThreadImpl[] { null };
653                 EvaluationContext context;
654                 org.netbeans.modules.debugger.jpda.expr.Evaluator evaluator =
655                     expression.evaluator (
656                         context = new EvaluationContext (
657                             frame,
658                             imports,
659                             staticImports,
660                             methodCallsUnsupportedExc == null,
661                             new Runnable JavaDoc() {
662                                 public void run() {
663                                     if (disabledBreakpoints[0] == null) {
664                                         disabledBreakpoints[0] = disableAllBreakpoints ();
665                                         resumedThread[0] = (JPDAThreadImpl) getThread(tr);
666                                         resumedThread[0].notifyMethodInvoking();
667                                     }
668                                 }
669                             },
670                             this
671                         )
672                     );
673                 try {
674                     return evaluator.evaluate ();
675                 } finally {
676                     if (methodCallsUnsupportedExc == null && !context.canInvokeMethods()) {
677                         methodCallsUnsupportedExc =
678                                 new InvalidExpressionException(new UnsupportedOperationException JavaDoc());
679                     }
680                     if (disabledBreakpoints[0] != null) {
681                         enableAllBreakpoints (disabledBreakpoints[0]);
682                     }
683                     if (resumedThread[0] != null) {
684                         resumedThread[0].notifyMethodInvokeDone();
685                     }
686                 }
687             } catch (EvaluationException e) {
688                 InvalidExpressionException iee = new InvalidExpressionException (e);
689                 iee.initCause (e);
690                 throw iee;
691             } catch (IncompatibleThreadStateException itsex) {
692                 ErrorManager.getDefault().notify(itsex);
693                 IllegalStateException JavaDoc isex = new IllegalStateException JavaDoc(itsex.getLocalizedMessage());
694                 isex.initCause(itsex);
695                 throw isex;
696             }
697         }
698     }
699     
700     /**
701      * Used by AbstractVariable.
702      */

703     public Value invokeMethod (
704         ObjectReference reference,
705         Method method,
706         Value[] arguments
707     ) throws InvalidExpressionException {
708         if (currentThread == null)
709             throw new InvalidExpressionException ("No current context");
710         synchronized (LOCK) {
711             if (methodCallsUnsupportedExc != null) {
712                 throw methodCallsUnsupportedExc;
713             }
714             List JavaDoc<EventRequest> l = disableAllBreakpoints ();
715             ThreadReference tr = getEvaluationThread();
716             JPDAThreadImpl thread = (JPDAThreadImpl) getThread(tr);
717             boolean threadSuspended = thread.isSuspended();
718             // Remember the current stack frame, it might be necessary to re-set.
719
CallStackFrameImpl csf = (CallStackFrameImpl)
720                 getCurrentCallStackFrame ();
721             JPDAThread frameThread = null;
722             if (csf != null) {
723                 try {
724                     frameThread = csf.getThread();
725                 } catch (InvalidStackFrameException isfex) {}
726             }
727             thread.notifyMethodInvoking();
728             try {
729                 return org.netbeans.modules.debugger.jpda.expr.Evaluator.
730                     invokeVirtual (
731                         reference,
732                         method,
733                         tr,
734                         Arrays.asList (arguments)
735                     );
736             } catch (InvalidExpressionException ieex) {
737                 if (ieex.getTargetException() instanceof UnsupportedOperationException JavaDoc) {
738                     methodCallsUnsupportedExc = ieex;
739                 }
740                 throw ieex;
741             } finally {
742                 if (threadSuspended) {
743                     thread.notifyMethodInvokeDone();
744                 }
745                 enableAllBreakpoints (l);
746                 if (frameThread != null) {
747                     try {
748                         csf.getThread();
749                     } catch (InvalidStackFrameException isfex) {
750                         // The current frame is invalidated, set the new current...
751
int depth = csf.getFrameDepth();
752                         try {
753                             CallStackFrame csf2 = frameThread.getCallStack(depth, depth + 1)[0];
754                             setCurrentCallStackFrameNoFire(csf2);
755                         } catch (AbsentInformationException aiex) {
756                             setCurrentCallStackFrame(null);
757                         }
758                     }
759                 }
760             }
761         }
762     }
763
764     public static String JavaDoc getGenericSignature (TypeComponent component) {
765         if (tcGenericSignatureMethod == null) return null;
766         try {
767             return (String JavaDoc) tcGenericSignatureMethod.invoke
768                 (component, new Object JavaDoc[0]);
769         } catch (IllegalAccessException JavaDoc e) {
770             e.printStackTrace();
771             return null; // should not happen
772
} catch (InvocationTargetException JavaDoc e) {
773             e.printStackTrace();
774             return null; // should not happen
775
}
776     }
777
778     public static String JavaDoc getGenericSignature (LocalVariable component) {
779         if (lvGenericSignatureMethod == null) return null;
780         try {
781             return (String JavaDoc) lvGenericSignatureMethod.invoke(component, new Object JavaDoc[0]);
782         } catch (IllegalAccessException JavaDoc e) {
783             e.printStackTrace();
784             return null; // should not happen
785
} catch (InvocationTargetException JavaDoc e) {
786             e.printStackTrace();
787             return null; // should not happen
788
}
789     }
790
791     public VirtualMachine getVirtualMachine () {
792         return virtualMachine;
793     }
794
795     public Operator getOperator () {
796         return operator;
797     }
798
799     public void setStarting () {
800         setState (STATE_STARTING);
801     }
802     
803     public void setRunning (VirtualMachine vm, Operator o) {
804         if (logger.isLoggable(Level.FINE)) {
805             logger.fine("Start - JPDADebuggerImpl.setRunning ()");
806             JPDAUtils.printFeatures (logger, vm);
807         }
808         synchronized (LOCK2) {
809             starting = true;
810         }
811         synchronized (this) {
812             virtualMachine = vm;
813         }
814         synchronized (canBeModifiedLock) {
815             canBeModified = null; // Reset the can be modified flag
816
}
817         
818         initGenericsSupport ();
819         
820         operator = o;
821         
822 // Iterator i = getVirtualMachine ().allThreads ().iterator ();
823
// while (i.hasNext ()) {
824
// ThreadReference tr = (ThreadReference) i.next ();
825
// if (tr.isSuspended ()) {
826
// if (startVerbose)
827
// System.out.println("\nS JPDADebuggerImpl.setRunning () - " +
828
// "thread supended"
829
// );
830
// setState (STATE_RUNNING);
831
// synchronized (LOCK) {
832
// virtualMachine.resume ();
833
// }
834
// if (startVerbose)
835
// System.out.println("\nS JPDADebuggerImpl.setRunning () - " +
836
// "thread supended - VM resumed - end"
837
// );
838
// synchronized (LOCK2) {
839
// LOCK2.notify ();
840
// }
841
// return;
842
// }
843
// }
844

845         setState (STATE_RUNNING);
846         synchronized (this) {
847             vm = virtualMachine; // re-take the VM, it can be nulled by finish()
848
}
849         if (vm != null) {
850             synchronized (LOCK) {
851                 vm.resume();
852             }
853         }
854         
855         logger.fine(" JPDADebuggerImpl.setRunning () finished, VM resumed.");
856         synchronized (LOCK2) {
857             starting = false;
858             LOCK2.notify ();
859         }
860     }
861
862     /**
863     * Performs stop action.
864     */

865     public void setStoppedState (ThreadReference thread) {
866         PropertyChangeEvent JavaDoc evt;
867         synchronized (LOCK) {
868             // this method can be called in stopped state to switch
869
// the current thread only
870
JPDAThread t = getThread (thread);
871             checkJSR45Languages (t);
872             evt = setCurrentThreadNoFire(t);
873             PropertyChangeEvent JavaDoc evt2 = setStateNoFire(STATE_STOPPED);
874             
875             if (evt == null) evt = evt2;
876             else if (evt2 != null) {
877                 PropertyChangeEvent JavaDoc evt3 = evt;
878                 while(evt3.getPropagationId() != null) evt3 = (PropertyChangeEvent JavaDoc) evt3.getPropagationId();
879                 evt3.setPropagationId(evt2);
880             }
881         }
882         if (evt != null) {
883             do {
884                 firePropertyChange(evt);
885                 evt = (PropertyChangeEvent JavaDoc) evt.getPropagationId();
886             } while (evt != null);
887         }
888     }
889     
890     /**
891     * Performs stop action and disable a next call to resume()
892     */

893     public void setStoppedStateNoContinue (ThreadReference thread) {
894         PropertyChangeEvent JavaDoc evt;
895         synchronized (LOCK) {
896             // this method can be called in stopped state to switch
897
// the current thread only
898
evt = setStateNoFire(STATE_RUNNING);
899             JPDAThread t = getThread (thread);
900             checkJSR45Languages (t);
901             PropertyChangeEvent JavaDoc evt2 = setCurrentThreadNoFire(t);
902             
903             if (evt == null) evt = evt2;
904             else if (evt2 != null) evt.setPropagationId(evt2);
905             
906             evt2 = setStateNoFire(STATE_STOPPED);
907             
908             if (evt == null) evt = evt2;
909             else if (evt2 != null) {
910                 PropertyChangeEvent JavaDoc evt3 = evt;
911                 while(evt3.getPropagationId() != null) evt3 = (PropertyChangeEvent JavaDoc) evt3.getPropagationId();
912                 evt3.setPropagationId(evt2);
913             }
914             
915             doContinue = false;
916         }
917         if (evt != null) {
918             do {
919                 firePropertyChange(evt);
920                 evt = (PropertyChangeEvent JavaDoc) evt.getPropagationId();
921             } while (evt != null);
922         }
923     }
924     
925     
926     private boolean finishing;
927
928     /**
929      * Used by KillActionProvider.
930      */

931     public void finish () {
932         //Workaround for #56233
933
//synchronized (LOCK) {
934
synchronized (this) {
935                 if (finishing) {
936                     // Can easily be called twice - from the operator termination
937
return ;
938                 }
939                 finishing = true;
940             }
941             logger.fine("StartActionProvider.finish ()");
942             AbstractDICookie di = (AbstractDICookie) lookupProvider.lookupFirst
943                 (null, AbstractDICookie.class);
944             if (getState () == STATE_DISCONNECTED) return;
945             Operator o = getOperator();
946             if (o != null) o.stop();
947             try {
948                 waitRunning(); // First wait till the debugger comes up
949
} catch (DebuggerStartException dsex) {
950                 // We do not want to start it anyway when we're finishing - do not bother
951
}
952             VirtualMachine vm;
953             synchronized (this) {
954                 vm = virtualMachine;
955             }
956             if (vm != null) {
957                 try {
958                     if (di instanceof AttachingDICookie) {
959                         logger.fine(" StartActionProvider.finish() VM dispose");
960                         vm.dispose ();
961                     } else {
962                         logger.fine(" StartActionProvider.finish() VM exit");
963                         vm.exit (0);
964                     }
965                 } catch (VMDisconnectedException e) {
966                     logger.fine(" StartActionProvider.finish() VM exception " + e);
967                     // debugee VM is already disconnected (it finished normally)
968
}
969             }
970             synchronized (this) {
971                 virtualMachine = null;
972             }
973             setState (STATE_DISCONNECTED);
974             if (jsr45EngineProviders != null) {
975                 for (Iterator JavaDoc<JSR45DebuggerEngineProvider> i = jsr45EngineProviders.iterator(); i.hasNext();) {
976                     JSR45DebuggerEngineProvider provider = i.next();
977                     provider.getDesctuctor().killEngine();
978                 }
979                 jsr45EngineProviders = null;
980             }
981             javaEngineProvider.getDestructor ().killEngine ();
982             logger.fine (" StartActionProvider.finish() end.");
983             
984             //Notify LOCK2 so that no one is waiting forever
985
synchronized (LOCK2) {
986                 starting = false;
987                 LOCK2.notify ();
988             }
989         //}
990
}
991
992     /**
993      * Suspends the target virtual machine (if any).
994      * Used by PauseActionProvider.
995      *
996      * @see com.sun.jdi.ThreadReference#suspend
997      */

998     public void suspend () {
999         VirtualMachine vm;
1000        synchronized (this) {
1001            vm = virtualMachine;
1002        }
1003        synchronized (LOCK) {
1004            if (getState () == STATE_STOPPED)
1005                return;
1006            if (vm != null) {
1007                logger.fine("VM suspend");
1008                vm.suspend ();
1009                // Check the suspended count
1010
List JavaDoc<ThreadReference> threads = vm.allThreads();
1011                for (ThreadReference t : threads) {
1012                    while (t.suspendCount() > 1) t.resume();
1013                }
1014            }
1015            setState (STATE_STOPPED);
1016        }
1017        notifySuspendAll();
1018    }
1019    
1020    public void notifySuspendAll() {
1021        Collection JavaDoc threads = threadsTranslation.getTranslated();
1022        for (Iterator JavaDoc it = threads.iterator(); it.hasNext(); ) {
1023            Object JavaDoc threadOrGroup = it.next();
1024            if (threadOrGroup instanceof JPDAThreadImpl) {
1025                ((JPDAThreadImpl) threadOrGroup).notifySuspended();
1026            }
1027        }
1028    }
1029    
1030    /**
1031     * Used by ContinueActionProvider & StepActionProvider.
1032     */

1033    public void resume () {
1034        synchronized (LOCK) {
1035            if (!doContinue) {
1036                doContinue = true;
1037                // Continue the next time and do nothing now.
1038
return ;
1039            }
1040        }
1041        if (operator.flushStaledEvents()) {
1042            return ;
1043        }
1044        setState (STATE_RUNNING);
1045        notifyToBeResumedAll();
1046        VirtualMachine vm;
1047        synchronized (this) {
1048            vm = virtualMachine;
1049        }
1050        synchronized (LOCK) {
1051            if (vm != null) {
1052                logger.fine("VM resume");
1053                vm.resume ();
1054            }
1055        }
1056    }
1057    
1058    /** DO NOT CALL FROM ANYWHERE BUT JPDAThreadImpl.resume(). */
1059    public boolean currentThreadToBeResumed() {
1060        synchronized (LOCK) {
1061            if (!doContinue) {
1062                doContinue = true;
1063                // Continue the next time and do nothing now.
1064
return false;
1065            }
1066        }
1067        if (operator.flushStaledEvents()) {
1068            return false;
1069        }
1070        setState (STATE_RUNNING);
1071        return true;
1072    }
1073    
1074    public void resumeCurrentThread() {
1075        synchronized (LOCK) {
1076            if (!doContinue) {
1077                doContinue = true;
1078                // Continue the next time and do nothing now.
1079
return ;
1080            }
1081        }
1082        if (operator.flushStaledEvents()) {
1083            return ;
1084        }
1085        setState (STATE_RUNNING);
1086        currentThread.resume();
1087    }
1088    
1089    public void notifyToBeResumedAll() {
1090        Collection JavaDoc threads = threadsTranslation.getTranslated();
1091        for (Iterator JavaDoc it = threads.iterator(); it.hasNext(); ) {
1092            Object JavaDoc threadOrGroup = it.next();
1093            if (threadOrGroup instanceof JPDAThreadImpl) {
1094                ((JPDAThreadImpl) threadOrGroup).notifyToBeResumed();
1095            }
1096        }
1097    }
1098    
1099    public JPDAThreadGroup[] getTopLevelThreadGroups() {
1100        VirtualMachine vm;
1101        synchronized (this) {
1102            vm = virtualMachine;
1103        }
1104        if (vm == null) {
1105            return new JPDAThreadGroup[0];
1106        }
1107        List JavaDoc groupList;
1108        synchronized (LOCK) {
1109            groupList = vm.topLevelThreadGroups();
1110        }
1111        JPDAThreadGroup[] groups = new JPDAThreadGroup[groupList.size()];
1112        for (int i = 0; i < groups.length; i++) {
1113            groups[i] = getThreadGroup((ThreadGroupReference) groupList.get(i));
1114        }
1115        return groups;
1116    }
1117
1118    public JPDAThread getThread (ThreadReference tr) {
1119        return (JPDAThread) threadsTranslation.translate (tr);
1120    }
1121
1122    public JPDAThreadGroup getThreadGroup (ThreadGroupReference tgr) {
1123        return (JPDAThreadGroup) threadsTranslation.translate (tgr);
1124    }
1125    
1126    public Variable getLocalVariable(LocalVariable lv, Value v) {
1127        return (Variable) localsTranslation.translate(lv, v);
1128    }
1129    
1130    public JPDAClassType getClassType(ReferenceType cr) {
1131        return (JPDAClassType) localsTranslation.translate (cr);
1132    }
1133
1134    public Variable getVariable (Value value) {
1135        return getLocalsTreeModel ().getVariable (value);
1136    }
1137    
1138    public ExpressionPool getExpressionPool() {
1139        return expressionPool;
1140    }
1141
1142
1143    // private helper methods ..................................................
1144

1145    private static final java.util.regex.Pattern JavaDoc jvmVersionPattern =
1146            java.util.regex.Pattern.compile ("(\\d+)\\.(\\d+)\\.(\\d+)(_\\d+)?(-\\w+)?");
1147    private static java.lang.reflect.Method JavaDoc tcGenericSignatureMethod;
1148    private static java.lang.reflect.Method JavaDoc lvGenericSignatureMethod;
1149
1150
1151    private void initGenericsSupport () {
1152        tcGenericSignatureMethod = null;
1153        if (Bootstrap.virtualMachineManager ().minorInterfaceVersion () >= 5) {
1154            VirtualMachine vm;
1155            synchronized (this) {
1156                vm = virtualMachine;
1157            }
1158            if (vm == null) return ;
1159            java.util.regex.Matcher JavaDoc m = jvmVersionPattern.matcher(vm.version ());
1160            if (m.matches ()) {
1161                int minor = Integer.parseInt (m.group (2));
1162                if (minor >= 5) {
1163                    try {
1164                        tcGenericSignatureMethod = TypeComponent.class.
1165                            getMethod ("genericSignature", new Class JavaDoc [0]);
1166                        lvGenericSignatureMethod = LocalVariable.class.
1167                            getMethod ("genericSignature", new Class JavaDoc [0]);
1168                    } catch (NoSuchMethodException JavaDoc e) {
1169                        // the method is not available, ignore generics
1170
}
1171                }
1172            }
1173        }
1174    }
1175    
1176    private PropertyChangeEvent JavaDoc setStateNoFire (int state) {
1177        if (state == this.state) return null;
1178        int o = this.state;
1179        this.state = state;
1180        //PENDING HACK see issue 46287
1181
System.setProperty(
1182            "org.openide.awt.SwingBrowserImpl.do-not-block-awt",
1183            String.valueOf (state != STATE_DISCONNECTED)
1184        );
1185        return new PropertyChangeEvent JavaDoc(this, PROP_STATE, new Integer JavaDoc (o), new Integer JavaDoc (state));
1186    }
1187
1188    private void setState (int state) {
1189        PropertyChangeEvent JavaDoc evt = setStateNoFire(state);
1190        if (evt != null) {
1191            firePropertyChange(evt);
1192        }
1193    }
1194
1195    /**
1196     * Fires property change.
1197     */

1198    private void firePropertyChange (String JavaDoc name, Object JavaDoc o, Object JavaDoc n) {
1199        pcs.firePropertyChange (name, o, n);
1200    }
1201
1202    /**
1203     * Fires property change.
1204     */

1205    private void firePropertyChange (PropertyChangeEvent JavaDoc evt) {
1206        pcs.firePropertyChange (evt);
1207    }
1208
1209    private SourcePath engineContext;
1210    public synchronized SourcePath getEngineContext () {
1211        if (engineContext == null)
1212            engineContext = (SourcePath) lookupProvider.
1213                lookupFirst (null, SourcePath.class);
1214        return engineContext;
1215    }
1216
1217    private LocalsTreeModel localsTreeModel;
1218    private LocalsTreeModel getLocalsTreeModel () {
1219        if (localsTreeModel == null)
1220            localsTreeModel = (LocalsTreeModel) lookupProvider.
1221                lookupFirst ("LocalsView", TreeModel.class);
1222        return localsTreeModel;
1223    }
1224
1225    private ThreadReference getEvaluationThread () {
1226        if (currentThread != null) return currentThread.getThreadReference ();
1227        VirtualMachine vm;
1228        synchronized (this) {
1229            vm = virtualMachine;
1230        }
1231        if (vm == null) return null;
1232        List JavaDoc l = vm.allThreads ();
1233        if (l.size () < 1) return null;
1234        int i, k = l.size ();
1235        ThreadReference thread = null;
1236        for (i = 0; i < k; i++) {
1237            ThreadReference t = (ThreadReference) l.get (i);
1238            if (t.isSuspended ()) {
1239                thread = t;
1240                if (t.name ().equals ("Finalizer"))
1241                    return t;
1242            }
1243        }
1244        return thread;
1245    }
1246
1247    private void updateCurrentCallStackFrame (JPDAThread thread) {
1248        if ( (thread == null) ||
1249             (thread.getStackDepth () < 1))
1250            setCurrentCallStackFrame (null);
1251        else
1252        try {
1253            setCurrentCallStackFrame (thread.getCallStack (0, 1) [0]);
1254        } catch (AbsentInformationException e) {
1255            setCurrentCallStackFrame (null);
1256        }
1257    }
1258
1259    /**
1260     * @param thread The thread to take the top frame from
1261     * @return A PropertyChangeEvent or <code>null</code>.
1262     */

1263    private PropertyChangeEvent JavaDoc updateCurrentCallStackFrameNoFire(JPDAThread thread) {
1264        CallStackFrame old;
1265        CallStackFrame callStackFrame;
1266        if ( (thread == null) ||
1267             (thread.getStackDepth () < 1))
1268            old = setCurrentCallStackFrameNoFire(callStackFrame = null);
1269        else
1270        try {
1271            old = setCurrentCallStackFrameNoFire(callStackFrame = thread.getCallStack (0, 1) [0]);
1272        } catch (AbsentInformationException e) {
1273            old = setCurrentCallStackFrameNoFire(callStackFrame = null);
1274        }
1275        if (old == callStackFrame) return null;
1276        else return new PropertyChangeEvent JavaDoc(this, PROP_CURRENT_CALL_STACK_FRAME,
1277                                            old, callStackFrame);
1278    }
1279    
1280    private List JavaDoc<EventRequest> disableAllBreakpoints () {
1281        List JavaDoc<EventRequest> l = new ArrayList JavaDoc<EventRequest>();
1282        VirtualMachine vm = getVirtualMachine ();
1283        if (vm == null) return l;
1284        EventRequestManager erm = vm.eventRequestManager ();
1285        l.addAll (erm.accessWatchpointRequests ());
1286        l.addAll (erm.breakpointRequests ());
1287        l.addAll (erm.classPrepareRequests ());
1288        l.addAll (erm.classUnloadRequests ());
1289        l.addAll (erm.exceptionRequests ());
1290        l.addAll (erm.methodEntryRequests ());
1291        l.addAll (erm.methodExitRequests ());
1292        l.addAll (erm.modificationWatchpointRequests ());
1293// l.addAll (erm.stepRequests ());
1294
l.addAll (erm.threadDeathRequests ());
1295        l.addAll (erm.threadStartRequests ());
1296        int i = l.size () - 1;
1297        for (; i >= 0; i--)
1298            if (!l.get (i).isEnabled ())
1299                l.remove (i);
1300            else
1301                l.get (i).disable ();
1302        operator.breakpointsDisabled();
1303        return l;
1304    }
1305    
1306    private void enableAllBreakpoints (List JavaDoc<EventRequest> l) {
1307        operator.breakpointsEnabled();
1308        int i, k = l.size ();
1309        for (i = 0; i < k; i++)
1310            try {
1311                l.get (i).enable ();
1312            } catch (IllegalThreadStateException JavaDoc ex) {
1313                // see #53163
1314
// this can occurre if there is some "old" StepRequest and
1315
// thread named in the request has died
1316
} catch (InvalidRequestStateException ex) {
1317                // workaround for #51176
1318
}
1319    }
1320
1321    private void checkJSR45Languages (JPDAThread t) {
1322        if (t.getStackDepth () > 0)
1323            try {
1324                CallStackFrame f = t.getCallStack (0, 1) [0];
1325                List JavaDoc l = f.getAvailableStrata ();
1326                int i, k = l.size ();
1327                for (i = 0; i < k; i++) {
1328                    if (!languages.contains (l.get (i))) {
1329                        String JavaDoc language = (String JavaDoc) l.get (i);
1330                        DebuggerManager.getDebuggerManager ().startDebugging (
1331                            createJSR45DI (language)
1332                        );
1333                        languages.add (language);
1334                    }
1335                } // for
1336
String JavaDoc stratum = f.getDefaultStratum ();
1337                if ( (stratum != null) &&
1338                     (!stratum.equals (lastStratumn))
1339                )
1340                    javaEngineProvider.getSession ().setCurrentLanguage (stratum);
1341                lastStratumn = stratum;
1342            } catch (AbsentInformationException e) {
1343                System.out.println("NoInformationException");
1344            }
1345    }
1346 
1347    private Set JavaDoc<JSR45DebuggerEngineProvider> jsr45EngineProviders;
1348
1349    private DebuggerInfo createJSR45DI (final String JavaDoc language) {
1350        if (jsr45EngineProviders == null) {
1351            jsr45EngineProviders = new HashSet JavaDoc<JSR45DebuggerEngineProvider>(1);
1352        }
1353        JSR45DebuggerEngineProvider provider = new JSR45DebuggerEngineProvider(language);
1354        jsr45EngineProviders.add(provider);
1355        return DebuggerInfo.create (
1356            "netbeans-jpda-JSR45DICookie-" + language,
1357            new Object JavaDoc[] {
1358                new DelegatingSessionProvider () {
1359                    public Session getSession (
1360                        DebuggerInfo debuggerInfo
1361                    ) {
1362                        return javaEngineProvider.getSession ();
1363                    }
1364                },
1365                provider
1366            }
1367        );
1368    }
1369    
1370    public JPDAStep createJPDAStep(int size, int depth) {
1371        Session session = (Session) lookupProvider.lookupFirst (null, Session.class);
1372        return new JPDAStepImpl(this, session, size, depth);
1373    }
1374}
1375
Popular Tags