KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > ui > JavaDebugHover


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.debug.ui;
12
13
14 import org.eclipse.debug.core.DebugException;
15 import org.eclipse.debug.core.model.IVariable;
16
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.widgets.Shell;
19
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IAdaptable;
22
23 import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
24 import org.eclipse.jface.preference.IPreferenceStore;
25
26 import org.eclipse.jface.text.BadLocationException;
27 import org.eclipse.jface.text.DefaultInformationControl;
28 import org.eclipse.jface.text.IDocument;
29 import org.eclipse.jface.text.IInformationControl;
30 import org.eclipse.jface.text.IInformationControlCreator;
31 import org.eclipse.jface.text.IRegion;
32 import org.eclipse.jface.text.ITextHoverExtension;
33 import org.eclipse.jface.text.ITextViewer;
34
35 import org.eclipse.ui.editors.text.EditorsUI;
36
37 import org.eclipse.ui.IEditorInput;
38 import org.eclipse.ui.IEditorPart;
39
40 import org.eclipse.debug.ui.DebugUITools;
41 import org.eclipse.debug.ui.IDebugUIConstants;
42
43 import org.eclipse.jdt.core.Flags;
44 import org.eclipse.jdt.core.IClassFile;
45 import org.eclipse.jdt.core.ICodeAssist;
46 import org.eclipse.jdt.core.IField;
47 import org.eclipse.jdt.core.IJavaElement;
48 import org.eclipse.jdt.core.ILocalVariable;
49 import org.eclipse.jdt.core.IMethod;
50 import org.eclipse.jdt.core.JavaModelException;
51 import org.eclipse.jdt.core.Signature;
52
53 import org.eclipse.jdt.debug.core.IJavaDebugTarget;
54 import org.eclipse.jdt.debug.core.IJavaReferenceType;
55 import org.eclipse.jdt.debug.core.IJavaStackFrame;
56 import org.eclipse.jdt.debug.core.IJavaThread;
57 import org.eclipse.jdt.debug.core.IJavaType;
58 import org.eclipse.jdt.debug.core.IJavaValue;
59 import org.eclipse.jdt.debug.core.IJavaVariable;
60
61 import org.eclipse.jdt.ui.JavaUI;
62 import org.eclipse.jdt.ui.text.java.hover.IJavaEditorTextHover;
63
64 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
65 import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIPlaceholderVariable;
66
67
68 public class JavaDebugHover implements IJavaEditorTextHover, ITextHoverExtension {
69     
70     private IEditorPart fEditor;
71         
72     /* (non-Javadoc)
73      * @see org.eclipse.jdt.ui.text.java.hover.IJavaEditorTextHover#setEditor(org.eclipse.ui.IEditorPart)
74      */

75     public void setEditor(IEditorPart editor) {
76         fEditor = editor;
77     }
78         
79     /* (non-Javadoc)
80      * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
81      */

82     public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
83         return JavaWordFinder.findWord(textViewer.getDocument(), offset);
84     }
85     
86     /**
87      * Returns the stack frame in which to search for variables, or <code>null</code>
88      * if none.
89      *
90      * @return the stack frame in which to search for variables, or <code>null</code>
91      * if none
92      */

93     protected IJavaStackFrame getFrame() {
94         IAdaptable adaptable = DebugUITools.getDebugContext();
95         if (adaptable != null) {
96             return (IJavaStackFrame)adaptable.getAdapter(IJavaStackFrame.class);
97         }
98         return null;
99     }
100         
101     /* (non-Javadoc)
102      * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
103      */

104     public String JavaDoc getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
105         IJavaStackFrame frame = getFrame();
106         if (frame != null) {
107             // first check for 'this' - code resolve does not resolve java elements for 'this'
108
IDocument document= textViewer.getDocument();
109             if (document != null) {
110                 try {
111                     String JavaDoc variableName= document.get(hoverRegion.getOffset(), hoverRegion.getLength());
112                     if (variableName.equals("this")) { //$NON-NLS-1$
113
try {
114                             IJavaVariable variable = frame.findVariable(variableName);
115                             if (variable != null) {
116                                 return getVariableText(variable);
117                             }
118                         } catch (DebugException e) {
119                             return null;
120                         }
121                     }
122                 } catch (BadLocationException e) {
123                     return null;
124                 }
125             }
126             ICodeAssist codeAssist = null;
127             if (fEditor != null) {
128                 IEditorInput input = fEditor.getEditorInput();
129                 Object JavaDoc element = JavaUI.getWorkingCopyManager().getWorkingCopy(input);
130                 if (element == null) {
131                     element = input.getAdapter(IClassFile.class);
132                 }
133                 if (element instanceof ICodeAssist) {
134                     codeAssist = ((ICodeAssist)element);
135                 }
136             }
137             if (codeAssist == null) {
138                 return getRemoteHoverInfo(frame, textViewer, hoverRegion);
139             }
140             
141             IJavaElement[] resolve = null;
142             try {
143                 resolve = codeAssist.codeSelect(hoverRegion.getOffset(), 0);
144             } catch (JavaModelException e1) {
145                 resolve = new IJavaElement[0];
146             }
147             try {
148                 for (int i = 0; i < resolve.length; i++) {
149                     IJavaElement javaElement = resolve[i];
150                     if (javaElement instanceof IField) {
151                         IField field = (IField)javaElement;
152                         IJavaVariable variable = null;
153                         IJavaDebugTarget debugTarget = (IJavaDebugTarget)frame.getDebugTarget();
154                         if (Flags.isStatic(field.getFlags())) {
155                             IJavaType[] javaTypes = debugTarget.getJavaTypes(field.getDeclaringType().getFullyQualifiedName());
156                             if (javaTypes != null) {
157                                 for (int j = 0; j < javaTypes.length; j++) {
158                                     IJavaType type = javaTypes[j];
159                                     if (type instanceof IJavaReferenceType) {
160                                         IJavaReferenceType referenceType = (IJavaReferenceType) type;
161                                         variable = referenceType.getField(field.getElementName());
162                                     }
163                                     if (variable != null) {
164                                         break;
165                                     }
166                                 }
167                             }
168                             if (variable == null) {
169                                 // the class is not loaded yet, but may be an in-lined primitive constant
170
Object JavaDoc constant = field.getConstant();
171                                 if (constant != null) {
172                                     IJavaValue value = null;
173                                     if (constant instanceof Integer JavaDoc) {
174                                         value = debugTarget.newValue(((Integer JavaDoc)constant).intValue());
175                                     } else if (constant instanceof Byte JavaDoc) {
176                                         value = debugTarget.newValue(((Byte JavaDoc)constant).byteValue());
177                                     } else if (constant instanceof Boolean JavaDoc) {
178                                         value = debugTarget.newValue(((Boolean JavaDoc)constant).booleanValue());
179                                     } else if (constant instanceof Character JavaDoc) {
180                                         value = debugTarget.newValue(((Character JavaDoc)constant).charValue());
181                                     } else if (constant instanceof Double JavaDoc) {
182                                         value = debugTarget.newValue(((Double JavaDoc)constant).doubleValue());
183                                     } else if (constant instanceof Float JavaDoc) {
184                                         value = debugTarget.newValue(((Float JavaDoc)constant).floatValue());
185                                     } else if (constant instanceof Long JavaDoc) {
186                                         value = debugTarget.newValue(((Long JavaDoc)constant).longValue());
187                                     } else if (constant instanceof Short JavaDoc) {
188                                         value = debugTarget.newValue(((Short JavaDoc)constant).shortValue());
189                                     } else if (constant instanceof String JavaDoc) {
190                                         value = debugTarget.newValue((String JavaDoc)constant);
191                                     }
192                                     if (value != null) {
193                                         variable = new JDIPlaceholderVariable(field.getElementName(), value);
194                                     }
195                                 }
196                                 if (variable == null) {
197                                     return null; // class not loaded yet and not a constant
198
}
199                             }
200                         } else {
201                             if (!frame.isStatic()) {
202                                 String JavaDoc typeSignature = Signature.createTypeSignature(field.getDeclaringType().getFullyQualifiedName(), true);
203                                 typeSignature = typeSignature.replace('.', '/');
204                                 variable = frame.getThis().getField(field.getElementName(), typeSignature);
205                             }
206                         }
207                         if (variable != null) {
208                             return getVariableText(variable);
209                         }
210                         break;
211                     }
212                     if (javaElement instanceof ILocalVariable) {
213                         ILocalVariable var = (ILocalVariable)javaElement;
214                         IJavaElement parent = var.getParent();
215                         while (!(parent instanceof IMethod) && parent != null) {
216                             parent = parent.getParent();
217                         }
218                         if (parent instanceof IMethod) {
219                             IMethod method = (IMethod) parent;
220                             boolean equal = false;
221                             if (method.isBinary()) {
222                                 // compare resolved signatures
223
if (method.getSignature().equals(frame.getSignature())) {
224                                     equal = true;
225                                 }
226                             } else {
227                                 // compare unresolved signatures
228
if (((frame.isConstructor() && method.isConstructor()) || frame.getMethodName().equals(method.getElementName()))
229                                         && frame.getDeclaringTypeName().endsWith(method.getDeclaringType().getElementName())
230                                         && frame.getArgumentTypeNames().size() == method.getNumberOfParameters()) {
231                                     equal = true;
232                                 }
233                             }
234                             if (equal) {
235                                 return generateHoverForLocal(frame, var.getElementName());
236                             }
237                         }
238                         break;
239                     }
240                 }
241             } catch (CoreException e) {
242                 JDIDebugPlugin.log(e);
243             }
244         }
245         return null;
246     }
247     
248     /**
249      * Generate hover info via a variable search, if the java element is not avilable.
250      */

251     private String JavaDoc getRemoteHoverInfo(IJavaStackFrame frame, ITextViewer textViewer, IRegion hoverRegion) {
252         if (frame != null) {
253             try {
254                 IDocument document= textViewer.getDocument();
255                 if (document != null) {
256                     String JavaDoc variableName= document.get(hoverRegion.getOffset(), hoverRegion.getLength());
257                     return generateHoverForLocal(frame, variableName);
258                 }
259             } catch (BadLocationException x) {
260             }
261         }
262         return null;
263     }
264     
265     private String JavaDoc generateHoverForLocal(IJavaStackFrame frame, String JavaDoc varName) {
266         String JavaDoc variableText= null;
267         try {
268             IVariable variable= frame.findVariable(varName);
269             if (variable != null) {
270                 variableText= getVariableText(variable);
271             }
272         } catch (DebugException x) {
273             if (x.getStatus().getCode() != IJavaThread.ERR_THREAD_NOT_SUSPENDED) {
274                 JDIDebugUIPlugin.log(x);
275             }
276         }
277         return variableText;
278     }
279
280     /**
281      * Returns HTML text for the given variable
282      */

283     private static String JavaDoc getVariableText(IVariable variable) {
284         StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
285         JDIModelPresentation modelPresentation = getModelPresentation();
286         buffer.append("<p><pre>"); //$NON-NLS-1$
287
String JavaDoc variableText= modelPresentation.getVariableText((IJavaVariable) variable);
288         buffer.append(replaceHTMLChars(variableText));
289         buffer.append("</pre></p>"); //$NON-NLS-1$
290
modelPresentation.dispose();
291         if (buffer.length() > 0) {
292             return buffer.toString();
293         }
294         return null;
295     }
296     
297     /**
298      * Replaces reserved HTML characters in the given string with
299      * their escaped equivalents. This is to ensure that variable
300      * values containing reserved characters are correctly displayed.
301      */

302     private static String JavaDoc replaceHTMLChars(String JavaDoc variableText) {
303         StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(variableText.length());
304         char[] characters = variableText.toCharArray();
305         for (int i = 0; i < characters.length; i++) {
306             char character= characters[i];
307             switch (character) {
308                 case '<':
309                     buffer.append("&lt;"); //$NON-NLS-1$
310
break;
311                 case '>':
312                     buffer.append("&gt;"); //$NON-NLS-1$
313
break;
314                 case '&':
315                     buffer.append("&amp;"); //$NON-NLS-1$
316
break;
317                 case '"':
318                     buffer.append("&quot;"); //$NON-NLS-1$
319
break;
320                 default:
321                     buffer.append(character);
322             }
323         }
324         return buffer.toString();
325     }
326
327     /**
328      * Returns a configured model presentation for use displaying variables.
329      */

330     private static JDIModelPresentation getModelPresentation() {
331         JDIModelPresentation presentation = new JDIModelPresentation();
332         
333         String JavaDoc[][] booleanPrefs= {
334                 {IJDIPreferencesConstants.PREF_SHOW_QUALIFIED_NAMES, JDIModelPresentation.DISPLAY_QUALIFIED_NAMES}};
335         String JavaDoc viewId= IDebugUIConstants.ID_VARIABLE_VIEW;
336         for (int i = 0; i < booleanPrefs.length; i++) {
337             boolean preferenceValue = getBooleanPreferenceValue(viewId, booleanPrefs[i][0]);
338             presentation.setAttribute(booleanPrefs[i][1], (preferenceValue ? Boolean.TRUE : Boolean.FALSE));
339         }
340         return presentation;
341     }
342     
343        /**
344      * Returns the value of this filters preference (on/off) for the given
345      * view.
346      *
347      * @param part
348      * @return boolean
349      */

350     public static boolean getBooleanPreferenceValue(String JavaDoc id, String JavaDoc preference) {
351         String JavaDoc compositeKey = id + "." + preference; //$NON-NLS-1$
352
IPreferenceStore store = JDIDebugUIPlugin.getDefault().getPreferenceStore();
353         boolean value = false;
354         if (store.contains(compositeKey)) {
355             value = store.getBoolean(compositeKey);
356         } else {
357             value = store.getBoolean(preference);
358         }
359         return value;
360     }
361
362     /* (non-Javadoc)
363      * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
364      */

365     public IInformationControlCreator getHoverControlCreator() {
366         return new IInformationControlCreator() {
367             public IInformationControl createInformationControl(Shell parent) {
368                 return new DefaultInformationControl(parent, SWT.NONE,
369                         new HTMLTextPresenter(true),
370                         EditorsUI.getTooltipAffordanceString());
371             }
372         };
373     }
374 }
375
Popular Tags