|
What this is
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.debugger.jpda.models;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.ArrayReference;
import com.sun.jdi.InvalidStackFrameException;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.NativeMethodException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.StackFrame;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.Value;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import org.netbeans.spi.debugger.ContextProvider;
import org.netbeans.api.debugger.jpda.JPDADebugger;
import org.netbeans.api.debugger.jpda.Variable;
import org.netbeans.spi.viewmodel.NoInformationException;
import org.netbeans.spi.viewmodel.TreeModel;
import org.netbeans.spi.viewmodel.TreeModelListener;
import org.netbeans.spi.viewmodel.UnknownTypeException;
import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl;
import org.openide.util.RequestProcessor;
/**
* @author Jan Jancura
*/
public class LocalsTreeModel implements TreeModel {
private static boolean verbose =
(System.getProperty ("netbeans.debugger.viewrefresh") != null) &&
(System.getProperty ("netbeans.debugger.viewrefresh").indexOf ('l') >= 0);
private JPDADebuggerImpl debugger;
private Listener listener;
private Vector listeners = new Vector ();
public LocalsTreeModel (ContextProvider lookupProvider) {
debugger = (JPDADebuggerImpl) lookupProvider.
lookupFirst (null, JPDADebugger.class);
}
public Object getRoot () {
return ROOT;
}
public Object[] getChildren (Object o, int from, int to)
throws NoInformationException, UnknownTypeException {
try {
if (o.equals (ROOT)) {
Object[] os = getLocalVariables (from, to);
return os;
} else
// if (o instanceof SuperVariable) {
// SuperVariable mv = (SuperVariable) o;
// return getSuperFields (mv, true, from, to);
// } else
if (o instanceof AbstractVariable) { // ThisVariable & FieldVariable
AbstractVariable mv = (AbstractVariable) o;
Object[] avs = mv.getFields (from, to);
// if (mv.getInnerValue () instanceof ArrayReference) {
// ArrayReference ar = (ArrayReference) mv.getInnerValue ();
// if (ar.length () > 50) {
// Object[] a2 = new Object [avs.length + 1];
// System.arraycopy (avs, 0, a2, 0, avs.length);
// a2 [avs.length] = "More";
// avs = a2;
// }
// }
return avs;
} else
throw new UnknownTypeException (o);
} catch (VMDisconnectedException ex) {
return new Object [0];
}
}
/**
* Returns number of children for given node.
*
* @param node the parent node
* @throws UnknownTypeException if this TreeModel implementation is not
* able to resolve children for given node type
*
* @return true if node is leaf
*/
public int getChildrenCount (Object node) throws UnknownTypeException,
NoInformationException {
try {
if (node.equals (ROOT)) {
CallStackFrameImpl frame = (CallStackFrameImpl) debugger.
getCurrentCallStackFrame ();
if (frame == null)
throw new NoInformationException ("No current thread");
StackFrame sf = frame.getStackFrame ();
if (sf == null)
throw new NoInformationException ("No current thread");
try {
int i = 0;
try {
i = sf.visibleVariables ().size ();
} catch (AbsentInformationException ex) {
i++;
}
if (sf.thisObject () != null) i++;
return i;
// } catch (AbsentInformationException ex) {
// throw new NoInformationException ("compiled without -g");
} catch (NativeMethodException ex) {
throw new NoInformationException ("native method");
} catch (InvalidStackFrameException ex) {
throw new NoInformationException ("thread is running");
} catch (VMDisconnectedException ex) {
}
return 0;
} else
// if (node instanceof SuperVariable) {
// SuperVariable mv = (SuperVariable) node;
// return getSuperFields (mv, true, 0, 0).length;
// } else
if (node instanceof AbstractVariable) { // ThisVariable & FieldVariable
AbstractVariable mv = (AbstractVariable) node;
// int i = 0;
// if (mv.getInnerValue () instanceof ArrayReference) {
// ArrayReference ar = (ArrayReference) mv.getInnerValue ();
// if (ar.length () > 50)
// i++;
// }
return mv.getFields (0, 0).length;
} else
throw new UnknownTypeException (node);
} catch (VMDisconnectedException ex) {
}
return 0;
}
public boolean isLeaf (Object o) throws UnknownTypeException {
if (o.equals (ROOT))
return false;
if (o instanceof AbstractVariable)
return !(((AbstractVariable) o).getInnerValue () instanceof ObjectReference);
if (o.equals ("More")) // NOI18N
return true;
if (o.equals ("NoInfo")) // NOI18N
return true;
throw new UnknownTypeException (o);
}
public void addTreeModelListener (TreeModelListener l) {
listeners.add (l);
if (listener == null)
listener = new Listener (this, debugger);
}
public void removeTreeModelListener (TreeModelListener l) {
listeners.remove (l);
if (listeners.size () == 0) {
listener.destroy ();
listener = null;
}
}
void fireTreeChanged () {
Vector v = (Vector) listeners.clone ();
int i, k = v.size ();
for (i = 0; i < k; i++)
((TreeModelListener) v.get (i)).treeChanged ();
}
void fireNodeChanged (Object n) {
Vector v = (Vector) listeners.clone ();
int i, k = v.size ();
for (i = 0; i < k; i++)
((TreeModelListener) v.get (i)).treeNodeChanged (n);
}
// private methods .........................................................
Object[] getLocalVariables (
int from,
int to
) throws NoInformationException {
synchronized (debugger.LOCK) {
CallStackFrameImpl callStackFrame = (CallStackFrameImpl) debugger.
getCurrentCallStackFrame ();
if (callStackFrame == null)
throw new NoInformationException ("No current thread");
StackFrame stackFrame = callStackFrame.getStackFrame ();
if (stackFrame == null)
throw new NoInformationException ("No current thread");
ObjectReference thisR = stackFrame.thisObject ();
if (thisR == null) {
Object[] avs = null;
try {
return getLocalVariables (
callStackFrame,
stackFrame,
from,
to
);
} catch (AbsentInformationException ex) {
throw new NoInformationException ("compiled without -g");
}
} else {
Object[] avs = null;
try {
avs = getLocalVariables (
callStackFrame,
stackFrame,
Math.max (from - 1, 0),
Math.max (to - 1, 0)
);
} catch (AbsentInformationException ex) {
avs = new Object[] {"NoInfo"};
}
Object[] result = new Object [avs.length + 1];
if (from < 1)
result [0] = getThis (thisR, "");
System.arraycopy (avs, 0, result, 1, avs.length);
return result;
}
} // synchronized
}
AbstractVariable[] getLocalVariables (
final CallStackFrameImpl callStackFrame,
final StackFrame stackFrame,
final int from,
final int to
) throws NoInformationException, AbsentInformationException {
try {
String className = stackFrame.location ().declaringType ().name ();
List l = stackFrame.visibleVariables ();
int i, k = to - from, j = from;
AbstractVariable[] locals = new AbstractVariable [k];
for (i = 0; i < k; i++) {
LocalVariable lv = (LocalVariable) l.get (j++);
locals [i] = getLocal (lv, callStackFrame, className);
}
return locals;
} catch (NativeMethodException ex) {
throw new NoInformationException ("native method");
} catch (InvalidStackFrameException ex) {
throw new NoInformationException ("thread is running");
} catch (VMDisconnectedException ex) {
return new AbstractVariable [0];
}
}
ThisVariable getThis (ObjectReference thisR, String parentID) {
return new ThisVariable (this, thisR, parentID);
}
private Local getLocal (LocalVariable lv, CallStackFrameImpl frame, String className) {
Value v = frame.getStackFrame ().getValue (lv);
if (v instanceof ObjectReference)
return new ObjectLocalVariable (
this,
v,
className,
lv,
JPDADebuggerImpl.getGenericSignature (lv),
frame
);
return new Local (this, v, className, lv, frame);
}
public Variable getVariable (Value v) {
if (v instanceof ObjectReference)
return new ObjectVariable (
this,
(ObjectReference) v,
null
);
return new AbstractVariable (this, v, null);
}
JPDADebuggerImpl getDebugger () {
return debugger;
}
// innerclasses ............................................................
private static class Listener implements PropertyChangeListener {
private JPDADebugger debugger;
private WeakReference model;
private Listener (
LocalsTreeModel tm,
JPDADebugger debugger
) {
this.debugger = debugger;
model = new WeakReference (tm);
debugger.addPropertyChangeListener (this);
}
void destroy () {
debugger.removePropertyChangeListener (this);
if (task != null) {
// cancel old task
task.cancel ();
if (verbose)
System.out.println("LTM cancel old task " + task);
task = null;
}
}
private LocalsTreeModel getModel () {
LocalsTreeModel tm = (LocalsTreeModel) model.get ();
if (tm == null) {
destroy ();
}
return tm;
}
// currently waiting / running refresh task
// there is at most one
private RequestProcessor.Task task;
public void propertyChange (PropertyChangeEvent e) {
if ( ( (e.getPropertyName () ==
JPDADebugger.PROP_CURRENT_CALL_STACK_FRAME) ||
//(e.getPropertyName () == debugger.PROP_CURRENT_THREAD) ||
(e.getPropertyName () == JPDADebugger.PROP_STATE)
) && (debugger.getState () == JPDADebugger.STATE_STOPPED)
) {
// IF state has been changed to STOPPED or
// IF current call stack frame has been changed & state is stoped
final LocalsTreeModel ltm = getModel ();
if (ltm == null) return;
if (task != null) {
// cancel old task
task.cancel ();
if (verbose)
System.out.println("LTM cancel old task " + task);
task = null;
}
task = RequestProcessor.getDefault ().post (new Runnable () {
public void run () {
if (debugger.getState () != JPDADebugger.STATE_STOPPED) {
if (verbose)
System.out.println("LTM cancel started task " + task);
return;
}
if (verbose)
System.out.println("LTM do task " + task);
ltm.fireTreeChanged ();
}
}, 500);
if (verbose)
System.out.println("LTM create task " + task);
} else
if ( (e.getPropertyName () == JPDADebugger.PROP_STATE) &&
(debugger.getState () != JPDADebugger.STATE_STOPPED) &&
(task != null)
) {
// debugger has been resumed
// =>> cancel task
task.cancel ();
if (verbose)
System.out.println("LTM cancel task " + task);
task = null;
}
}
}
}
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.