KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > launcher > PDESourceLookupQuery


1 /*******************************************************************************
2  * Copyright (c) 2006, 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.pde.internal.ui.launcher;
12
13 import java.io.File JavaDoc;
14 import java.util.ArrayList JavaDoc;
15
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.resources.IProject;
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.resources.IWorkspaceRoot;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.core.runtime.ISafeRunnable;
23 import org.eclipse.core.runtime.Path;
24 import org.eclipse.debug.core.DebugException;
25 import org.eclipse.debug.core.model.IValue;
26 import org.eclipse.debug.core.sourcelookup.ISourceContainer;
27 import org.eclipse.debug.core.sourcelookup.containers.ArchiveSourceContainer;
28 import org.eclipse.debug.core.sourcelookup.containers.ExternalArchiveSourceContainer;
29 import org.eclipse.jdt.core.IClasspathEntry;
30 import org.eclipse.jdt.core.IJavaElement;
31 import org.eclipse.jdt.core.IJavaProject;
32 import org.eclipse.jdt.core.IPackageFragmentRoot;
33 import org.eclipse.jdt.core.JavaCore;
34 import org.eclipse.jdt.core.JavaModelException;
35 import org.eclipse.jdt.debug.core.IJavaClassType;
36 import org.eclipse.jdt.debug.core.IJavaFieldVariable;
37 import org.eclipse.jdt.debug.core.IJavaObject;
38 import org.eclipse.jdt.debug.core.IJavaReferenceType;
39 import org.eclipse.jdt.debug.core.IJavaStackFrame;
40 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
41 import org.eclipse.jdt.launching.JavaRuntime;
42 import org.eclipse.osgi.service.resolver.BundleDescription;
43 import org.eclipse.osgi.service.resolver.State;
44 import org.eclipse.pde.core.plugin.IPluginModelBase;
45 import org.eclipse.pde.core.plugin.ModelEntry;
46 import org.eclipse.pde.core.plugin.PluginRegistry;
47 import org.eclipse.pde.internal.core.PDEClasspathContainer;
48 import org.eclipse.pde.internal.core.PDECore;
49 import org.eclipse.pde.internal.core.TargetPlatformHelper;
50 import org.eclipse.pde.internal.ui.PDEPlugin;
51
52 public class PDESourceLookupQuery implements ISafeRunnable {
53     
54     protected static String JavaDoc OSGI_CLASSLOADER = "org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader"; //$NON-NLS-1$
55
private static String JavaDoc LEGACY_ECLIPSE_CLASSLOADER = "org.eclipse.core.runtime.adaptor.EclipseClassLoader"; //$NON-NLS-1$
56
private static String JavaDoc MAIN_CLASS = "org.eclipse.core.launcher.Main"; //$NON-NLS-1$
57
private static String JavaDoc MAIN_PLUGIN = "org.eclipse.platform"; //$NON-NLS-1$
58

59     private Object JavaDoc fElement;
60     private Object JavaDoc fResult;
61     
62     public PDESourceLookupQuery(Object JavaDoc object) {
63         fElement = object;
64     }
65
66     public void handleException(Throwable JavaDoc exception) {
67     }
68
69     public void run() throws Exception JavaDoc {
70         IJavaObject classLoaderObject = null;
71         String JavaDoc declaringTypeName = null;
72         String JavaDoc sourcePath = null;
73         if (fElement instanceof IJavaStackFrame) {
74             IJavaStackFrame stackFrame = (IJavaStackFrame)fElement;
75             classLoaderObject = stackFrame.getReferenceType().getClassLoaderObject();
76             declaringTypeName = stackFrame.getDeclaringTypeName();
77             sourcePath = generateSourceName(declaringTypeName);
78         } else if (fElement instanceof IJavaObject){
79             IJavaObject object = (IJavaObject)fElement;
80             IJavaReferenceType type = (IJavaReferenceType)object.getJavaType();
81             classLoaderObject = type.getClassLoaderObject();
82             if (object.getJavaType() != null){
83                 declaringTypeName = object.getJavaType().getName();
84             }
85             if (declaringTypeName != null){
86                 sourcePath = generateSourceName(declaringTypeName);
87             }
88         } else if (fElement instanceof IJavaReferenceType){
89             IJavaReferenceType type = (IJavaReferenceType)fElement;
90             classLoaderObject = type.getClassLoaderObject();
91             declaringTypeName = type.getName();
92             sourcePath = generateSourceName(declaringTypeName);
93         }
94             
95         if (classLoaderObject != null) {
96             IJavaClassType type = (IJavaClassType)classLoaderObject.getJavaType();
97             if (OSGI_CLASSLOADER.equals(type.getName())) {
98                 fResult = findSourceElement(classLoaderObject, sourcePath);
99             } else if (LEGACY_ECLIPSE_CLASSLOADER.equals(type.getName())) {
100                 fResult = findSourceElement_legacy(classLoaderObject, sourcePath);
101             } else if (MAIN_CLASS.equals(declaringTypeName)){
102                 IPluginModelBase model = PDECore.getDefault().getModelManager().findModel(MAIN_PLUGIN);
103                 if (model != null)
104                     fResult = getSourceElement(model.getInstallLocation(), MAIN_PLUGIN, sourcePath);
105             }
106         }
107     }
108     
109     protected Object JavaDoc getResult() {
110         return fResult;
111     }
112     
113     private String JavaDoc getValue(IJavaObject object, String JavaDoc variable) throws DebugException {
114         IJavaFieldVariable var = object.getField(variable, false);
115         return var == null ? null : var.getValue().getValueString();
116     }
117     
118     protected Object JavaDoc findSourceElement(IJavaObject object, String JavaDoc typeName) throws CoreException {
119         IJavaObject manager = getObject(object, "manager", false); //$NON-NLS-1$
120
if (manager != null) {
121             IJavaObject data = getObject(manager, "data", false); //$NON-NLS-1$
122
if (data != null) {
123                 String JavaDoc location = getValue(data, "fileName"); //$NON-NLS-1$
124
String JavaDoc id = getValue(data, "symbolicName"); //$NON-NLS-1$
125
return getSourceElement(location, id, typeName);
126             }
127         }
128         return null;
129     }
130     
131     private IJavaObject getObject(IJavaObject object, String JavaDoc field, boolean superfield) throws DebugException {
132         IJavaFieldVariable variable = object.getField(field, superfield);
133         if (variable != null) {
134             IValue value = variable.getValue();
135             if (value instanceof IJavaObject)
136                 return (IJavaObject)value;
137         }
138         return null;
139     }
140     
141     private Object JavaDoc findSourceElement_legacy(IJavaObject object, String JavaDoc typeName) throws CoreException {
142         IJavaObject hostdata = getObject(object, "hostdata", true); //$NON-NLS-1$
143
if (hostdata != null) {
144             String JavaDoc location = getValue(hostdata, "fileName"); //$NON-NLS-1$
145
String JavaDoc id = getValue(hostdata, "symbolicName"); //$NON-NLS-1$
146
return getSourceElement(location, id, typeName);
147         }
148         return null;
149     }
150     
151     private Object JavaDoc getSourceElement(String JavaDoc location, String JavaDoc id, String JavaDoc typeName) throws CoreException {
152         if (location != null && id != null) {
153             Object JavaDoc result = findSourceElement(getSourceContainers(location, id), typeName);
154             if (result != null)
155                 return result;
156             
157             // don't give up yet, search fragments attached to this host
158
State state = TargetPlatformHelper.getState();
159             BundleDescription desc = state.getBundle(id, null);
160             if (desc != null) {
161                 BundleDescription[] fragments = desc.getFragments();
162                 for (int i = 0; i < fragments.length; i++) {
163                     location = fragments[i].getLocation();
164                     id = fragments[i].getSymbolicName();
165                     result = findSourceElement(getSourceContainers(location, id), typeName);
166                     if (result != null)
167                         return result;
168                 }
169             }
170         }
171         return null;
172     }
173     
174     private Object JavaDoc findSourceElement(ISourceContainer[] containers, String JavaDoc typeName) throws CoreException {
175         for (int i = 0; i < containers.length; i++) {
176             Object JavaDoc[] result = containers[i].findSourceElements(typeName);
177             if (result.length > 0)
178                 return result[0];
179         }
180         return null;
181     }
182     
183     protected ISourceContainer[] getSourceContainers(String JavaDoc location, String JavaDoc id) throws CoreException {
184         ArrayList JavaDoc result = new ArrayList JavaDoc();
185         ModelEntry entry = PluginRegistry.findEntry(id);
186         
187         boolean match = false;
188
189         IPluginModelBase[] models = entry.getWorkspaceModels();
190         for (int i = 0; i < models.length; i++) {
191             if (isPerfectMatch(models[i], new Path(location))) {
192                 IResource resource = models[i].getUnderlyingResource();
193                 // if the plug-in matches a workspace model,
194
// add the project and any libraries not coming via a container
195
// to the list of source containers, in that order
196
if (resource != null) {
197                     addProjectSourceContainers(resource.getProject(), result);
198                 }
199                 match = true;
200                 break;
201             }
202         }
203
204         if (!match) {
205             File JavaDoc file = new File JavaDoc(location);
206             if (file.isFile()) {
207                 // in case of linked plug-in projects that map to an external JARd plug-in,
208
// use source container that maps to the library in the linked project.
209
ISourceContainer container = getArchiveSourceContainer(location);
210                 if (container != null)
211                     return new ISourceContainer[] {container};
212             }
213             
214             models = entry.getExternalModels();
215             for (int i = 0; i < models.length; i++) {
216                 if (isPerfectMatch(models[i], new Path(location))) {
217                     // try all source zips found in the source code locations
218
IClasspathEntry[] entries = PDEClasspathContainer.getExternalEntries(models[i]);
219                     for (int j = 0; j < entries.length; j++) {
220                         IRuntimeClasspathEntry rte = convertClasspathEntry(entries[j]);
221                         if (rte != null)
222                             result.add(rte);
223                     }
224                     break;
225                 }
226             }
227         }
228         
229         IRuntimeClasspathEntry[] entries = (IRuntimeClasspathEntry[])
230                             result.toArray(new IRuntimeClasspathEntry[result.size()]);
231         return JavaRuntime.getSourceContainers(entries);
232     }
233     
234     private void addProjectSourceContainers(IProject project, ArrayList JavaDoc result) throws CoreException {
235         if (project == null || !project.hasNature(JavaCore.NATURE_ID))
236             return;
237         
238         IJavaProject jProject = JavaCore.create(project);
239         result.add(JavaRuntime.newProjectRuntimeClasspathEntry(jProject));
240         
241         IClasspathEntry[] entries = jProject.getRawClasspath();
242         for (int i = 0; i < entries.length; i++) {
243             IClasspathEntry entry = entries[i];
244             if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
245                 IRuntimeClasspathEntry rte = convertClasspathEntry(entry);
246                 if (rte != null)
247                     result.add(rte);
248             }
249         }
250     }
251     
252     private IRuntimeClasspathEntry convertClasspathEntry(IClasspathEntry entry) {
253         if (entry == null)
254             return null;
255         
256         IPath srcPath = entry.getSourceAttachmentPath();
257         if (srcPath != null && srcPath.segmentCount() > 0) {
258             IRuntimeClasspathEntry rte =
259                 JavaRuntime.newArchiveRuntimeClasspathEntry(entry.getPath());
260             rte.setSourceAttachmentPath(srcPath);
261             rte.setSourceAttachmentRootPath(entry.getSourceAttachmentRootPath());
262             return rte;
263         }
264         return null;
265     }
266     
267     private boolean isPerfectMatch(IPluginModelBase model, IPath path) {
268         return model == null ? false : path.equals(new Path(model.getInstallLocation()));
269     }
270     
271     private ISourceContainer getArchiveSourceContainer(String JavaDoc location) throws JavaModelException {
272         IWorkspaceRoot root = PDEPlugin.getWorkspace().getRoot();
273         IFile[] containers = root.findFilesForLocation(new Path(location));
274         for (int i = 0; i < containers.length; i++) {
275             IJavaElement element = JavaCore.create(containers[i]);
276             if (element instanceof IPackageFragmentRoot) {
277                 IPackageFragmentRoot archive = (IPackageFragmentRoot)element;
278                 IPath path = archive.getSourceAttachmentPath();
279                 if (path == null || path.segmentCount() == 0)
280                     continue;
281                 
282                 IPath rootPath = archive.getSourceAttachmentRootPath();
283                 boolean detectRootPath = rootPath != null && rootPath.segmentCount() > 0;
284                 
285                 IFile archiveFile = root.getFile(path);
286                 if (archiveFile.exists())
287                     return new ArchiveSourceContainer(archiveFile, detectRootPath);
288                 
289                 File JavaDoc file = path.toFile();
290                 if (file.exists())
291                     return new ExternalArchiveSourceContainer(file.getAbsolutePath(), detectRootPath);
292             }
293         }
294         return null;
295     }
296     /**
297      * Generates and returns a source file path based on a qualified type name.
298      * For example, when <code>java.lang.String</code> is provided,
299      * the returned source name is <code>java/lang/String.java</code>.
300      *
301      * @param qualifiedTypeName fully qualified type name that may contain inner types
302      * denoted with <code>$</code> character
303      * @return a source file path corresponding to the type name
304      */

305     private static String JavaDoc generateSourceName(String JavaDoc qualifiedTypeName) {
306         int index = qualifiedTypeName.indexOf('$');
307         if (index >= 0)
308             qualifiedTypeName = qualifiedTypeName.substring(0, index);
309         return qualifiedTypeName.replace('.', File.separatorChar) + ".java"; //$NON-NLS-1$
310
}
311
312 }
Popular Tags