1 19 20 package org.netbeans.modules.debugger.jpda.projects; 21 22 import java.io.IOException ; 23 import java.lang.reflect.InvocationTargetException ; 24 import java.util.List ; 25 import javax.swing.JEditorPane ; 26 import javax.swing.SwingUtilities ; 27 import javax.swing.text.BadLocationException ; 28 import javax.swing.text.Element ; 29 import javax.swing.text.StyledDocument ; 30 import org.openide.ErrorManager; 31 32 import org.openide.cookies.EditorCookie; 33 import org.openide.loaders.DataObject; 34 import org.openide.text.Annotation; 35 import org.openide.text.DataEditorSupport; 36 import org.openide.text.Line; 37 import org.openide.text.NbDocument; 38 import org.openide.text.Line.Part; 39 import org.openide.util.RequestProcessor; 40 import org.netbeans.api.debugger.DebuggerEngine; 41 import org.netbeans.api.debugger.DebuggerManager; 42 import org.netbeans.api.debugger.jpda.InvalidExpressionException; 43 import org.netbeans.api.debugger.Watch; 44 import org.netbeans.api.debugger.jpda.JPDADebugger; 45 import org.netbeans.api.debugger.jpda.JPDAThread; 46 import org.netbeans.api.debugger.jpda.JPDAWatch; 47 import org.netbeans.api.debugger.jpda.ObjectVariable; 48 import org.netbeans.api.debugger.jpda.Variable; 49 import org.netbeans.spi.debugger.jpda.EditorContext.Operation; 50 51 import org.openide.nodes.Node; 52 import org.openide.windows.TopComponent; 53 54 55 public class ToolTipAnnotation extends Annotation implements Runnable { 56 57 private Part lp; 58 private EditorCookie ec; 59 60 public String getShortDescription () { 61 DebuggerEngine currentEngine = DebuggerManager.getDebuggerManager (). 62 getCurrentEngine (); 63 if (currentEngine == null) return null; 64 JPDADebugger d = (JPDADebugger) currentEngine.lookupFirst 65 (null, JPDADebugger.class); 66 if (d == null) return null; 67 68 Part lp = (Part) getAttachedAnnotatable(); 69 if (lp == null) return null; 70 Line line = lp.getLine (); 71 DataObject dob = DataEditorSupport.findDataObject (line); 72 if (dob == null) return null; 73 EditorCookie ec = (EditorCookie) dob.getCookie (EditorCookie.class); 74 if (ec == null) 75 return null; 76 78 this.lp = lp; 79 this.ec = ec; 80 RequestProcessor.getDefault ().post (this); 81 return null; 82 } 83 84 public void run () { 85 if (lp == null || ec == null) return ; 86 StyledDocument doc; 87 try { 88 doc = ec.openDocument(); 89 } catch (IOException ex) { 90 return ; 91 } 92 JEditorPane ep = getCurrentEditor (); 93 if (ep == null) return ; 94 int offset; 95 String expression = getIdentifier ( 96 doc, 97 ep, 98 offset = NbDocument.findLineOffset ( 99 doc, 100 lp.getLine ().getLineNumber () 101 ) + lp.getColumn () 102 ); 103 if (expression == null) return ; 104 DebuggerEngine currentEngine = DebuggerManager.getDebuggerManager (). 105 getCurrentEngine (); 106 if (currentEngine == null) return; 107 JPDADebugger d = (JPDADebugger) currentEngine.lookupFirst 108 (null, JPDADebugger.class); 109 if (d == null) return; 110 JPDAThread t = d.getCurrentThread(); 111 if (t == null || !t.isSuspended()) return ; 112 String toolTipText = null; 113 try { 114 Variable v = null; 115 List <Operation> operations = t.getLastOperations(); 116 if (operations != null) { 117 for (Operation operation: operations) { 118 if (!expression.endsWith(operation.getMethodName())) { 119 continue; 120 } 121 if (operation.getMethodStartPosition().getOffset() <= offset && 122 offset <= operation.getMethodEndPosition().getOffset()) { 123 v = operation.getReturnValue(); 124 } 125 } 126 } 127 if (v == null) { 128 v = d.evaluate (expression); 129 } 130 String type = v.getType (); 131 String value = v.getValue (); 132 if (v instanceof ObjectVariable) 133 try { 134 toolTipText = expression + " = " + 135 (type.length () == 0 ? 136 "" : 137 "(" + type + ") ") + 138 ((ObjectVariable) v).getToStringValue (); 139 } catch (InvalidExpressionException ex) { 140 toolTipText = expression + " = " + 141 (type.length () == 0 ? 142 "" : 143 "(" + type + ") ") + 144 value; 145 } 146 else 147 toolTipText = expression + " = " + 148 (type.length () == 0 ? 149 "" : 150 "(" + type + ") ") + 151 value; 152 } catch (InvalidExpressionException e) { 153 toolTipText = expression + " = >" + e.getMessage () + "<"; 154 } 155 firePropertyChange (PROP_SHORT_DESCRIPTION, null, toolTipText); 156 } 157 158 public String getAnnotationType () { 159 return null; } 161 162 private static String getIdentifier ( 163 StyledDocument doc, 164 JEditorPane ep, 165 int offset 166 ) { 167 String t = null; 168 if ( (ep.getSelectionStart () <= offset) && 169 (offset <= ep.getSelectionEnd ()) 170 ) t = ep.getSelectedText (); 171 if (t != null) return t; 172 173 int line = NbDocument.findLineNumber ( 174 doc, 175 offset 176 ); 177 int col = NbDocument.findLineColumn ( 178 doc, 179 offset 180 ); 181 try { 182 Element lineElem = 183 NbDocument.findLineRootElement (doc). 184 getElement (line); 185 186 if (lineElem == null) return null; 187 int lineStartOffset = lineElem.getStartOffset (); 188 int lineLen = lineElem.getEndOffset() - lineStartOffset; 189 t = doc.getText (lineStartOffset, lineLen); 190 int identStart = col; 191 while (identStart > 0 && 192 (Character.isJavaIdentifierPart ( 193 t.charAt (identStart - 1) 194 ) || 195 (t.charAt (identStart - 1) == '.'))) { 196 identStart--; 197 } 198 int identEnd = col; 199 while (identEnd < lineLen && 200 Character.isJavaIdentifierPart(t.charAt(identEnd)) 201 ) { 202 identEnd++; 203 } 204 205 if (identStart == identEnd) return null; 206 return t.substring (identStart, identEnd); 207 } catch (BadLocationException e) { 208 return null; 209 } 210 } 211 212 217 private static JEditorPane getCurrentEditor_() { 218 EditorCookie e = getCurrentEditorCookie (); 219 if (e == null) return null; 220 JEditorPane [] op = e.getOpenedPanes (); 221 if ((op == null) || (op.length < 1)) return null; 222 return op [0]; 223 } 224 225 private static JEditorPane getCurrentEditor () { 226 if (SwingUtilities.isEventDispatchThread()) { 227 return getCurrentEditor_(); 228 } else { 229 final JEditorPane [] ce = new JEditorPane [1]; 230 try { 231 SwingUtilities.invokeAndWait(new Runnable () { 232 public void run() { 233 ce[0] = getCurrentEditor_(); 234 } 235 }); 236 } catch (InvocationTargetException ex) { 237 ErrorManager.getDefault().notify(ex.getTargetException()); 238 } catch (InterruptedException ex) { 239 ErrorManager.getDefault().notify(ex); 240 } 241 return ce[0]; 242 } 243 } 244 245 250 private static EditorCookie getCurrentEditorCookie () { 251 Node[] nodes = TopComponent.getRegistry ().getActivatedNodes (); 252 if ( (nodes == null) || 253 (nodes.length != 1) ) return null; 254 Node n = nodes [0]; 255 return (EditorCookie) n.getCookie ( 256 EditorCookie.class 257 ); 258 } 259 } 260 261 | Popular Tags |