KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > core > JavaDebugUtils


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 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.core;
12
13 import java.io.File JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IAdaptable;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.Path;
22 import org.eclipse.debug.core.DebugException;
23 import org.eclipse.debug.core.ILaunch;
24 import org.eclipse.debug.core.model.ISourceLocator;
25 import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
26 import org.eclipse.jdt.core.IClassFile;
27 import org.eclipse.jdt.core.ICompilationUnit;
28 import org.eclipse.jdt.core.IJavaElement;
29 import org.eclipse.jdt.core.IJavaProject;
30 import org.eclipse.jdt.core.IType;
31 import org.eclipse.jdt.core.JavaCore;
32 import org.eclipse.jdt.debug.core.IJavaReferenceType;
33 import org.eclipse.jdt.debug.core.IJavaStackFrame;
34 import org.eclipse.jdt.debug.core.IJavaThread;
35 import org.eclipse.jdt.debug.core.IJavaType;
36 import org.eclipse.jdt.debug.core.IJavaValue;
37
38 import com.sun.jdi.VMDisconnectedException;
39
40 /**
41  * A Utilities class.
42  *
43  * @since 3.2
44  */

45 public class JavaDebugUtils {
46
47     /**
48      * Resolves and returns a type from the Java model that corresponds to the
49      * declaring type of the given stack frame, or <code>null</code> if none.
50      *
51      * @param frame frame to resolve declaring type for
52      * @return corresponding Java model type or <code>null</code>
53      * @exception CoreException if an exception occurs during the resolution
54      * @since 3.2
55      */

56     public static IType resolveDeclaringType(IJavaStackFrame frame) throws CoreException {
57         IJavaElement javaElement = resolveJavaElement(frame, frame.getLaunch());
58         if (javaElement != null) {
59             return resolveType(frame.getDeclaringTypeName(), javaElement);
60         }
61         return null;
62     }
63     
64     /**
65      * Resolves and returns a type from the Java model that corresponds to the
66      * type of the given value, or <code>null</code> if none.
67      *
68      * @param value value to resolve type for
69      * @return corresponding Java model type or <code>null</code>
70      * @exception CoreException if an exception occurs during the resolution
71      */

72     public static IType resolveType(IJavaValue value) throws CoreException {
73         IJavaElement javaElement = resolveJavaElement(value, value.getLaunch());
74         if (javaElement != null) {
75             return resolveType(value.getJavaType().getName(), javaElement);
76         }
77         return null;
78     }
79     
80     /**
81      * Resolves and returns the Java model type associated with the given
82      * Java debug type, or <code>null</code> if none.
83      *
84      * @param type Java debug model type
85      * @return Java model type or <code>null</code>
86      * @throws CoreException
87      */

88     public static IType resolveType(IJavaType type) throws CoreException {
89         IJavaElement element = resolveJavaElement(type, type.getLaunch());
90         if (element != null ) {
91             return resolveType(type.getName(), element);
92         }
93         return null;
94     }
95     
96     /**
97      * Returns the source name associated with the given object, or <code>null</code>
98      * if none.
99      *
100      * @param object an object with an <code>IJavaStackFrame</code> adapter, an IJavaValue
101      * or an IJavaType
102      * @return the source name associated with the given object, or <code>null</code>
103      * if none
104      * @exception CoreException if unable to retrieve the source name
105      */

106     public static String JavaDoc getSourceName(Object JavaDoc object) throws CoreException {
107         if (object instanceof String JavaDoc) {
108             // assume it's a file name
109
return (String JavaDoc)object;
110         }
111         IJavaStackFrame frame = null;
112         if (object instanceof IAdaptable) {
113             frame = (IJavaStackFrame) ((IAdaptable)object).getAdapter(IJavaStackFrame.class);
114         }
115         String JavaDoc typeName = null;
116         try {
117             if (frame != null) {
118                 if (frame.isObsolete()) {
119                     return null;
120                 }
121                 String JavaDoc sourceName = frame.getSourcePath();
122                 // TODO: this may break fix to bug 21518
123
if (sourceName == null) {
124                     // no debug attributes, guess at source name
125
typeName = frame.getDeclaringTypeName();
126                 } else {
127                     return sourceName;
128                 }
129             } else {
130                 if (object instanceof IJavaValue) {
131                     // look at its type
132
object = ((IJavaValue)object).getJavaType();
133                 }
134                 if (object instanceof IJavaReferenceType) {
135                     IJavaReferenceType refType = (IJavaReferenceType)object;
136                     String JavaDoc[] sourcePaths = refType.getSourcePaths(null);
137                     if (sourcePaths != null && sourcePaths.length > 0) {
138                         return sourcePaths[0];
139                     }
140                 }
141                 if (object instanceof IJavaType) {
142                     typeName = ((IJavaType)object).getName();
143                 }
144             }
145         } catch (DebugException e) {
146             int code = e.getStatus().getCode();
147             if (code == IJavaThread.ERR_THREAD_NOT_SUSPENDED || code == IJavaStackFrame.ERR_INVALID_STACK_FRAME ||
148                     e.getStatus().getException() instanceof VMDisconnectedException) {
149                 return null;
150             }
151             throw e;
152         }
153         if (typeName != null) {
154             return generateSourceName(typeName);
155         }
156         return null;
157     }
158     
159     /**
160      * Generates and returns a source file path based on a qualified type name.
161      * For example, when <code>java.lang.String</code> is provided,
162      * the returned source name is <code>java/lang/String.java</code>.
163      *
164      * @param qualifiedTypeName fully qualified type name that may contain inner types
165      * denoted with <code>$</code> character
166      * @return a source file path corresponding to the type name
167      */

168     public static String JavaDoc generateSourceName(String JavaDoc qualifiedTypeName) {
169         int index = qualifiedTypeName.lastIndexOf('.');
170         if (index < 0) {
171             index = 0;
172         }
173         qualifiedTypeName = qualifiedTypeName.replace('.', File.separatorChar);
174         index = qualifiedTypeName.indexOf('$');
175         if (index >= 0) {
176             qualifiedTypeName = qualifiedTypeName.substring(0, index);
177         }
178         if (qualifiedTypeName.length() == 0) {
179             // likely a proxy class (see bug 40815)
180
qualifiedTypeName = null;
181         } else {
182             qualifiedTypeName = qualifiedTypeName + ".java"; //$NON-NLS-1$
183
}
184         return qualifiedTypeName;
185     }
186     
187     /**
188      * Resolves the type corresponding to the given name contained in the given top-level
189      * Java element (class file, compilation unit, or type).
190      *
191      * @param qualifiedName fully qualified type name
192      * @param javaElement java element containing the type
193      * @return type
194      * @throws CoreException
195      */

196     private static IType resolveType(String JavaDoc qualifiedName, IJavaElement javaElement) throws CoreException {
197         IType type = null;
198         String JavaDoc[] typeNames = getNestedTypeNames(qualifiedName);
199         if (javaElement instanceof IClassFile) {
200             type = ((IClassFile)javaElement).getType();
201         } else if (javaElement instanceof ICompilationUnit) {
202             type = ((ICompilationUnit)javaElement).getType(typeNames[0]);
203         } else if (javaElement instanceof IType) {
204             type = (IType)javaElement;
205         }
206         if (type != null) {
207             for (int i = 1; i < typeNames.length; i++) {
208                 String JavaDoc innerTypeName= typeNames[i];
209                 try {
210                     Integer.parseInt(innerTypeName);
211                     return type;
212                 } catch (NumberFormatException JavaDoc e) {
213                 }
214                 type = type.getType(innerTypeName);
215             }
216         }
217         return type;
218     }
219     
220     /**
221      * Returns the Java element corresponding to the given object or <code>null</code>
222      * if none, in the context of the given launch.
223      *
224      * @param launch provides source locator
225      * @param object object to resolve Java model element for
226      * @return corresponding Java element or <code>null</code>
227      * @throws CoreException
228      */

229     private static IJavaElement resolveJavaElement(Object JavaDoc object, ILaunch launch) throws CoreException {
230         Object JavaDoc sourceElement = resolveSourceElement(object, launch);
231         IJavaElement javaElement = null;
232         if (sourceElement instanceof IJavaElement) {
233             javaElement = (IJavaElement) sourceElement;
234         } else if (sourceElement instanceof IAdaptable) {
235             javaElement = (IJavaElement) ((IAdaptable)sourceElement).getAdapter(IJavaElement.class);
236         }
237         if (javaElement == null && sourceElement instanceof IResource) {
238             javaElement= JavaCore.create((IResource)sourceElement);
239         }
240         if (javaElement == null) {
241             return null;
242         }
243         if (!javaElement.exists()) {
244             return null;
245         }
246         return javaElement;
247     }
248     
249     /**
250      * Returns the source element corresponding to the given object or <code>null</code>
251      * if none, in the context of the given launch.
252      *
253      * @param launch provides source locator
254      * @param object object to resolve source element for
255      * @return corresponding source element or <code>null</code>
256      * @throws CoreException
257      */

258     public static Object JavaDoc resolveSourceElement(Object JavaDoc object, ILaunch launch) throws CoreException {
259         ISourceLocator sourceLocator = launch.getSourceLocator();
260         if (sourceLocator instanceof ISourceLookupDirector) {
261             ISourceLookupDirector director = (ISourceLookupDirector) sourceLocator;
262             Object JavaDoc[] objects = director.findSourceElements(object);
263             if (objects.length > 0) {
264                  return objects[0];
265             }
266         }
267         return null;
268     }
269
270     /**
271      * Returns an array of simple type names that are
272      * part of the given type's qualified name. For
273      * example, if the given name is <code>x.y.A$B</code>,
274      * an array with <code>["A", "B"]</code> is returned.
275      *
276      * @param typeName fully qualified type name
277      * @return array of nested type names
278      */

279     private static String JavaDoc[] getNestedTypeNames(String JavaDoc typeName) {
280         int index = typeName.lastIndexOf('.');
281         if (index >= 0) {
282             typeName= typeName.substring(index + 1);
283         }
284         index = typeName.indexOf('$');
285         List JavaDoc list = new ArrayList JavaDoc(1);
286         while (index >= 0) {
287             list.add(typeName.substring(0, index));
288             typeName = typeName.substring(index + 1);
289             index = typeName.indexOf('$');
290         }
291         list.add(typeName);
292         return (String JavaDoc[])list.toArray(new String JavaDoc[list.size()]);
293     }
294     
295     /**
296      * Returns the class file or compilation unit containing the given fully qualified name in the
297      * specified project. All registered java like file extensions are considered.
298      *
299      * @param qualifiedTypeName fully qualified type name
300      * @param project project to search in
301      * @return class file or compilation unit or <code>null</code>
302      */

303     public static IJavaElement findElement(String JavaDoc qualifiedTypeName, IJavaProject project) throws CoreException{
304         String JavaDoc[] javaLikeExtensions = JavaCore.getJavaLikeExtensions();
305         String JavaDoc path = qualifiedTypeName;
306         int pos = path.indexOf('$');
307         if (pos != -1) {
308             path= path.substring(0, pos);
309         }
310         path = path.replace('.', IPath.SEPARATOR);
311         path += "."; //$NON-NLS-1$
312
for (int i = 0; i < javaLikeExtensions.length; i++) {
313             String JavaDoc ext = javaLikeExtensions[i];
314             IJavaElement element = project.findElement(new Path(path + ext));
315             if (element != null) {
316                 return element;
317             }
318         }
319         return null;
320     }
321 }
322
Popular Tags