1 11 package org.eclipse.pde.internal.ui.launcher; 12 13 import java.io.File ; 14 import java.util.ArrayList ; 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 OSGI_CLASSLOADER = "org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader"; private static String LEGACY_ECLIPSE_CLASSLOADER = "org.eclipse.core.runtime.adaptor.EclipseClassLoader"; private static String MAIN_CLASS = "org.eclipse.core.launcher.Main"; private static String MAIN_PLUGIN = "org.eclipse.platform"; 59 private Object fElement; 60 private Object fResult; 61 62 public PDESourceLookupQuery(Object object) { 63 fElement = object; 64 } 65 66 public void handleException(Throwable exception) { 67 } 68 69 public void run() throws Exception { 70 IJavaObject classLoaderObject = null; 71 String declaringTypeName = null; 72 String 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 getResult() { 110 return fResult; 111 } 112 113 private String getValue(IJavaObject object, String variable) throws DebugException { 114 IJavaFieldVariable var = object.getField(variable, false); 115 return var == null ? null : var.getValue().getValueString(); 116 } 117 118 protected Object findSourceElement(IJavaObject object, String typeName) throws CoreException { 119 IJavaObject manager = getObject(object, "manager", false); if (manager != null) { 121 IJavaObject data = getObject(manager, "data", false); if (data != null) { 123 String location = getValue(data, "fileName"); String id = getValue(data, "symbolicName"); return getSourceElement(location, id, typeName); 126 } 127 } 128 return null; 129 } 130 131 private IJavaObject getObject(IJavaObject object, String 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 findSourceElement_legacy(IJavaObject object, String typeName) throws CoreException { 142 IJavaObject hostdata = getObject(object, "hostdata", true); if (hostdata != null) { 144 String location = getValue(hostdata, "fileName"); String id = getValue(hostdata, "symbolicName"); return getSourceElement(location, id, typeName); 147 } 148 return null; 149 } 150 151 private Object getSourceElement(String location, String id, String typeName) throws CoreException { 152 if (location != null && id != null) { 153 Object result = findSourceElement(getSourceContainers(location, id), typeName); 154 if (result != null) 155 return result; 156 157 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 findSourceElement(ISourceContainer[] containers, String typeName) throws CoreException { 175 for (int i = 0; i < containers.length; i++) { 176 Object [] 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 location, String id) throws CoreException { 184 ArrayList result = new ArrayList (); 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 (resource != null) { 197 addProjectSourceContainers(resource.getProject(), result); 198 } 199 match = true; 200 break; 201 } 202 } 203 204 if (!match) { 205 File file = new File (location); 206 if (file.isFile()) { 207 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 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 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 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 file = path.toFile(); 290 if (file.exists()) 291 return new ExternalArchiveSourceContainer(file.getAbsolutePath(), detectRootPath); 292 } 293 } 294 return null; 295 } 296 305 private static String generateSourceName(String qualifiedTypeName) { 306 int index = qualifiedTypeName.indexOf('$'); 307 if (index >= 0) 308 qualifiedTypeName = qualifiedTypeName.substring(0, index); 309 return qualifiedTypeName.replace('.', File.separatorChar) + ".java"; } 311 312 } | Popular Tags |