KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > ui > console > JavaStackTraceHyperlink


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.console;
12
13
14 import org.eclipse.core.runtime.CoreException;
15 import org.eclipse.core.runtime.IProgressMonitor;
16 import org.eclipse.core.runtime.IStatus;
17 import org.eclipse.core.runtime.Status;
18 import org.eclipse.core.runtime.jobs.Job;
19 import org.eclipse.debug.core.ILaunch;
20 import org.eclipse.debug.core.model.IProcess;
21 import org.eclipse.debug.ui.IDebugModelPresentation;
22 import org.eclipse.debug.ui.IDebugUIConstants;
23 import org.eclipse.jdt.core.JavaCore;
24 import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
25 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
26 import org.eclipse.jdt.internal.debug.ui.actions.OpenTypeAction;
27 import org.eclipse.jface.dialogs.ErrorDialog;
28 import org.eclipse.jface.dialogs.MessageDialog;
29 import org.eclipse.jface.text.BadLocationException;
30 import org.eclipse.jface.text.IDocument;
31 import org.eclipse.jface.text.IRegion;
32 import org.eclipse.ui.IEditorInput;
33 import org.eclipse.ui.IEditorPart;
34 import org.eclipse.ui.console.IHyperlink;
35 import org.eclipse.ui.console.TextConsole;
36 import org.eclipse.ui.progress.UIJob;
37 import org.eclipse.ui.texteditor.IDocumentProvider;
38 import org.eclipse.ui.texteditor.ITextEditor;
39
40 import com.ibm.icu.text.MessageFormat;
41
42 /**
43  * A hyperlink from a stack trace line of the form "*(*.java:*)"
44  */

45 public class JavaStackTraceHyperlink implements IHyperlink {
46     
47     private TextConsole fConsole;
48
49     /**
50      * Constructor for JavaStackTraceHyperlink.
51      */

52     public JavaStackTraceHyperlink(TextConsole console) {
53         fConsole = console;
54     }
55
56     /**
57      * @see org.eclipse.debug.ui.console.IConsoleHyperlink#linkEntered()
58      */

59     public void linkEntered() {
60     }
61
62     /**
63      * @see org.eclipse.debug.ui.console.IConsoleHyperlink#linkExited()
64      */

65     public void linkExited() {
66     }
67
68     /**
69      * @see org.eclipse.debug.ui.console.IConsoleHyperlink#linkActivated()
70      */

71     public void linkActivated() {
72         String JavaDoc typeName;
73         int lineNumber;
74         try {
75             String JavaDoc linkText = getLinkText();
76             typeName = getTypeName(linkText);
77             lineNumber = getLineNumber(linkText);
78         } catch (CoreException e1) {
79             ErrorDialog.openError(JDIDebugUIPlugin.getActiveWorkbenchShell(), ConsoleMessages.JavaStackTraceHyperlink_Error, ConsoleMessages.JavaStackTraceHyperlink_Error, e1.getStatus());
80             return;
81         }
82         
83         // documents start at 0
84
if (lineNumber > 0) {
85             lineNumber--;
86         }
87         startSourceSearch(typeName, lineNumber);
88     }
89     
90     /**
91      * Starts a search for the type with the given name. Reports back to 'searchCompleted(...)'.
92      *
93      * @param typeName the type to search for
94      */

95     protected void startSourceSearch(final String JavaDoc typeName, final int lineNumber) {
96         Job search = new Job(ConsoleMessages.JavaStackTraceHyperlink_2) {
97             protected IStatus run(IProgressMonitor monitor) {
98                 ILaunch launch = getLaunch();
99                 Object JavaDoc result = null;
100                 try {
101                     if (launch != null) {
102                         result = JavaDebugUtils.resolveSourceElement(JavaDebugUtils.generateSourceName(typeName), getLaunch());
103                     }
104                     if (result == null) {
105                         // search for the type in the workspace
106
result = OpenTypeAction.findTypeInWorkspace(typeName);
107                     }
108                     searchCompleted(result, typeName, lineNumber, null);
109                 } catch (CoreException e) {
110                     searchCompleted(null, typeName, lineNumber, e.getStatus());
111                 }
112                 return Status.OK_STATUS;
113             }
114         
115         };
116         search.schedule();
117     }
118     
119     protected void searchCompleted(final Object JavaDoc source, final String JavaDoc typeName, final int lineNumber, final IStatus status) {
120         UIJob job = new UIJob("link search complete") { //$NON-NLS-1$
121
public IStatus runInUIThread(IProgressMonitor monitor) {
122                 if (source == null) {
123                     if (status == null) {
124                         // did not find source
125
MessageDialog.openInformation(JDIDebugUIPlugin.getActiveWorkbenchShell(), ConsoleMessages.JavaStackTraceHyperlink_Information_1, MessageFormat.format(ConsoleMessages.JavaStackTraceHyperlink_Source_not_found_for__0__2, new String JavaDoc[] {typeName}));
126                     } else {
127                         JDIDebugUIPlugin.statusDialog(ConsoleMessages.JavaStackTraceHyperlink_3, status);
128                     }
129                 } else {
130                     processSearchResult(source, typeName, lineNumber);
131                 }
132                 return Status.OK_STATUS;
133             }
134         };
135         job.setSystem(true);
136         job.schedule();
137     }
138     
139     /**
140      * The search succeeded with the given result
141      *
142      * @param source resolved source object for the search
143      * @param typeName type name searched for
144      * @param lineNumber line number on link
145      */

146     protected void processSearchResult(Object JavaDoc source, String JavaDoc typeName, int lineNumber) {
147         IDebugModelPresentation presentation = JDIDebugUIPlugin.getDefault().getModelPresentation();
148         IEditorInput editorInput = presentation.getEditorInput(source);
149         if (editorInput != null) {
150             String JavaDoc editorId = presentation.getEditorId(editorInput, source);
151             if (editorId != null) {
152                 try {
153                     IEditorPart editorPart = JDIDebugUIPlugin.getActivePage().openEditor(editorInput, editorId);
154                     if (editorPart instanceof ITextEditor && lineNumber >= 0) {
155                         ITextEditor textEditor = (ITextEditor)editorPart;
156                         IDocumentProvider provider = textEditor.getDocumentProvider();
157                         provider.connect(editorInput);
158                         IDocument document = provider.getDocument(editorInput);
159                         try {
160                             IRegion line = document.getLineInformation(lineNumber);
161                             textEditor.selectAndReveal(line.getOffset(), line.getLength());
162                         } catch (BadLocationException e) {
163                             MessageDialog.openInformation(JDIDebugUIPlugin.getActiveWorkbenchShell(), ConsoleMessages.JavaStackTraceHyperlink_0, MessageFormat.format("{0}{1}{2}", new String JavaDoc[] {(lineNumber+1)+"", ConsoleMessages.JavaStackTraceHyperlink_1, typeName})); //$NON-NLS-2$ //$NON-NLS-1$
164
}
165                         provider.disconnect(editorInput);
166                     }
167                 } catch (CoreException e) {
168                     JDIDebugUIPlugin.statusDialog(e.getStatus());
169                 }
170             }
171         }
172     }
173
174     /**
175      * Returns the launch associated with this hyperlink, or
176      * <code>null</code> if none
177      *
178      * @return the launch associated with this hyperlink, or
179      * <code>null</code> if none
180      */

181     private ILaunch getLaunch() {
182         IProcess process = (IProcess) getConsole().getAttribute(IDebugUIConstants.ATTR_CONSOLE_PROCESS);
183         if (process != null) {
184             return process.getLaunch();
185         }
186         return null;
187     }
188
189     /**
190      * Returns the fully qualified name of the type to open
191      *
192      * @return fully qualified type name
193      * @exception CoreException if unable to parse the type name
194      */

195     protected String JavaDoc getTypeName(String JavaDoc linkText) throws CoreException {
196         int start = linkText.indexOf('(');
197         int end = linkText.indexOf(':');
198         if (start >= 0 && end > start) {
199             //linkText could be something like packageA.TypeB(TypeA.java:45)
200
//need to look in packageA.TypeA for line 45 since TypeB is defined
201
//in TypeA.java
202
//Inner classes can be ignored because we're using file and line number
203

204             // get File name (w/o .java)
205
String JavaDoc typeName = linkText.substring(start + 1, end);
206             typeName = JavaCore.removeJavaLikeExtension(typeName);
207
208             String JavaDoc qualifier = linkText.substring(0, start);
209             // remove the method name
210
start = qualifier.lastIndexOf('.');
211
212             if (start >= 0) {
213                 // remove the class name
214
start = new String JavaDoc((String JavaDoc) qualifier.subSequence(0, start)).lastIndexOf('.');
215                 if (start == -1) {
216                     start = 0; // default package
217
}
218             }
219
220             if (start >= 0) {
221                 qualifier = qualifier.substring(0, start);
222             }
223             
224             if (qualifier.length() > 0) {
225                 typeName = qualifier + "." + typeName; //$NON-NLS-1$
226
}
227             return typeName;
228         }
229         IStatus status = new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), 0, ConsoleMessages.JavaStackTraceHyperlink_Unable_to_parse_type_name_from_hyperlink__5, null);
230         throw new CoreException(status);
231     }
232     
233     /**
234      * Returns the line number associated with the stack trace or -1 if none.
235      *
236      * @exception CoreException if unable to parse the number
237      */

238     protected int getLineNumber(String JavaDoc linkText) throws CoreException {
239         int index = linkText.lastIndexOf(':');
240         if (index >= 0) {
241             String JavaDoc numText = linkText.substring(index + 1);
242             index = numText.indexOf(')');
243             if (index >= 0) {
244                 numText = numText.substring(0, index);
245             }
246             try {
247                 return Integer.parseInt(numText);
248             } catch (NumberFormatException JavaDoc e) {
249                 IStatus status = new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), 0, ConsoleMessages.JavaStackTraceHyperlink_Unable_to_parse_line_number_from_hyperlink__6, e);
250                 throw new CoreException(status);
251             }
252         }
253         IStatus status = new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), 0, ConsoleMessages.JavaStackTraceHyperlink_Unable_to_parse_line_number_from_hyperlink__6, null);
254         throw new CoreException(status);
255     }
256     
257     /**
258      * Returns the console this link is contained in.
259      *
260      * @return console
261      */

262     protected TextConsole getConsole() {
263         return fConsole;
264     }
265     
266     /**
267      * Returns this link's text
268      *
269      * @exception CoreException if unable to retrieve the text
270      */

271     protected String JavaDoc getLinkText() throws CoreException {
272         try {
273             IDocument document = getConsole().getDocument();
274             IRegion region = getConsole().getRegion(this);
275             int regionOffset = region.getOffset();
276             
277             int lineNumber = document.getLineOfOffset(regionOffset);
278             IRegion lineInformation = document.getLineInformation(lineNumber);
279             int lineOffset = lineInformation.getOffset();
280             String JavaDoc line = document.get(lineOffset, lineInformation.getLength());
281             
282             int regionOffsetInLine = regionOffset - lineOffset;
283
284             int linkEnd = line.indexOf(')', regionOffsetInLine);
285             int linkStart = line.lastIndexOf(' ', regionOffsetInLine);
286             
287             return line.substring(linkStart==-1?0:linkStart+1,linkEnd+1);
288         } catch (BadLocationException e) {
289             IStatus status = new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), 0, ConsoleMessages.JavaStackTraceHyperlink_Unable_to_retrieve_hyperlink_text__8, e);
290             throw new CoreException(status);
291         }
292     }
293
294 }
295
Popular Tags