Copyright (c) 2000, 2017 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2000, 2017 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.jdt.internal.launching; import java.io.File; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.debug.core.sourcelookup.ISourceContainer; import org.eclipse.debug.core.sourcelookup.containers.DirectorySourceContainer; import org.eclipse.debug.core.sourcelookup.containers.ExternalArchiveSourceContainer; import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer; import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer; import org.eclipse.jdt.core.IJavaModel; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.launching.IRuntimeClasspathEntry; import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer; import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer;
Private source lookup utilities. Translates runtime classpath entries to source containers.
Since:3.0
/** * Private source lookup utilities. Translates runtime classpath entries * to source containers. * * @since 3.0 */
public class JavaSourceLookupUtil {
Translates the given runtime classpath entries into associated source containers.
Params:
  • entries – entries to translate
Returns:source containers corresponding to the given runtime classpath entries
/** * Translates the given runtime classpath entries into associated source * containers. * * @param entries entries to translate * @return source containers corresponding to the given runtime classpath entries */
public static ISourceContainer[] translate(IRuntimeClasspathEntry[] entries) { List<ISourceContainer> containers = new ArrayList<>(entries.length); for (int i = 0; i < entries.length; i++) { IRuntimeClasspathEntry entry = entries[i]; switch (entry.getType()) { case IRuntimeClasspathEntry.ARCHIVE: if (entry.getPath().lastSegment().equals("jrt-fs.jar")) { //$NON-NLS-1$ getPackageFragmentRootContainers(entry, containers); } else { IPackageFragmentRoot root = getPackageFragmentRoot(entry); if (root == null) { addSourceAttachment(entry, containers); } else { ISourceContainer container = new PackageFragmentRootSourceContainer(root); if (!containers.contains(container)) { containers.add(container); } } } break; case IRuntimeClasspathEntry.PROJECT: IResource resource = entry.getResource(); if (resource != null && resource.getType() == IResource.PROJECT) { IJavaProject javaProject = JavaCore.create((IProject)resource); ISourceContainer container = null; if (javaProject.exists()) { container = new JavaProjectSourceContainer(javaProject); } else if (resource.exists()) { container = new ProjectSourceContainer((IProject)resource, false); } if (container != null && !containers.contains(container)) { containers.add(container); } } break; default: // no other classpath types are valid in a resolved path break; } } return containers.toArray(new ISourceContainer[containers.size()]); }
Tries to find and attach source containers for given runtime classpath entry
Params:
  • entry – non null
  • containers –
/** * Tries to find and attach source containers for given runtime classpath entry * * @param entry * non null * @param containers */
private static void addSourceAttachment(IRuntimeClasspathEntry entry, List<ISourceContainer> containers) { String path = entry.getSourceAttachmentLocation(); ISourceContainer container = null; if (path == null) { // use the archive itself path = entry.getLocation(); } if (path != null) { // check if file or folder File file = new File(path); if (file.isDirectory()) { IResource resource = entry.getResource(); if (resource instanceof IContainer) { container = new FolderSourceContainer((IContainer) resource, false); } else { container = new DirectorySourceContainer(file, false); } } else { container = new ExternalArchiveSourceContainer(path, true); } if (!containers.contains(container)) { containers.add(container); } } }
Returns whether the source attachments of the given package fragment root and runtime classpath entry are equal.

NOTE: If the runtime classpath entry's source attachment is not specified, then it is considered equal. This way, the corresponding package fragment root is used for source lookup if it has a source attachment or not.

Params:
  • root – package fragment root
  • entry – runtime classpath entry
Throws:
Returns:whether the source attachments of the given package fragment root and runtime classpath entry are equal
/** * Returns whether the source attachments of the given package fragment * root and runtime classpath entry are equal. * <p> * NOTE: If the runtime classpath entry's source attachment is not specified, * then it is considered equal. This way, the corresponding package fragment * root is used for source lookup if it has a source attachment or not. * </p> * * @param root package fragment root * @param entry runtime classpath entry * @return whether the source attachments of the given package fragment * root and runtime classpath entry are equal * @throws JavaModelException if there is a problem accessing the given {@link IPackageFragmentRoot} */
private static boolean isSourceAttachmentEqual(IPackageFragmentRoot root, IRuntimeClasspathEntry entry) throws JavaModelException { IPath entryPath = entry.getSourceAttachmentPath(); if (entryPath == null) { return true; } IPath rootPath = root.getSourceAttachmentPath(); if (rootPath == null) { // entry has a source attachment that the package root does not return false; } return rootPath.equals(entryPath); }
Determines if the given archive runtime classpath entry exists in the workspace as a package fragment root. Returns the associated package fragment root or null if none.
Params:
  • entry – archive runtime classpath entry
Returns:package fragment root or null
/** * Determines if the given archive runtime classpath entry exists * in the workspace as a package fragment root. Returns the associated * package fragment root or <code>null</code> if none. * * @param entry archive runtime classpath entry * @return package fragment root or <code>null</code> */
private static IPackageFragmentRoot getPackageFragmentRoot(IRuntimeClasspathEntry entry) { IResource resource = entry.getResource(); if (resource != null) { // find package fragment associated with the resource IProject project = resource.getProject(); IJavaProject jp = JavaCore.create(project); try { if (project.isOpen() && jp.exists()) { IPackageFragmentRoot root = jp.findPackageFragmentRoot(resource.getFullPath()); if (root != null && isSourceAttachmentEqual(root, entry)) { // use package fragment root return root; } } } catch (JavaModelException e) { LaunchingPlugin.log(e); } } // Check all package fragment roots for case of external archive. // External jars are shared, so it does not matter which project it // originates from IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()); IPath entryPath = entry.getPath(); try { IJavaProject[] jps = model.getJavaProjects(); for (int i = 0; i < jps.length; i++) { IJavaProject jp = jps[i]; IProject p = jp.getProject(); if (p.isOpen()) { IPackageFragmentRoot[] allRoots = jp.getPackageFragmentRoots(); for (int j = 0; j < allRoots.length; j++) { IPackageFragmentRoot root = allRoots[j]; if (root.getPath().equals(entryPath) && isSourceAttachmentEqual(root, entry)) { // use package fragment root return root; } } } } } catch (JavaModelException e) { LaunchingPlugin.log(e); } return null; }
Determines the package fragment roots from the java model and adds corresponding PackageFragmentRootSourceContainer to the list of containers if their source attachment and path is same as the entry.
Params:
  • entry – archive runtime classpath entry for jrt-fs.jar
  • containers – container list to be updated
/** * Determines the package fragment roots from the java model and adds corresponding PackageFragmentRootSourceContainer to the list of containers * if their source attachment and path is same as the entry. * * @param entry * archive runtime classpath entry for jrt-fs.jar * @param containers * container list to be updated */
private static void getPackageFragmentRootContainers(IRuntimeClasspathEntry entry, List<ISourceContainer> containers) { IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()); IPath entryPath = entry.getPath(); boolean found = false; try { IJavaProject[] jps = model.getJavaProjects(); for (int i = 0; i < jps.length; i++) { IJavaProject jp = jps[i]; IProject p = jp.getProject(); if (p.isOpen()) { IPackageFragmentRoot[] allRoots = jp.getPackageFragmentRoots(); for (int j = 0; j < allRoots.length; j++) { IPackageFragmentRoot root = allRoots[j]; if (root.getPath().equals(entryPath) && isSourceAttachmentEqual(root, entry)) { PackageFragmentRootSourceContainer container = new PackageFragmentRootSourceContainer(root); if (!containers.contains(container)) { containers.add(container); found = true; } } } } } } catch (JavaModelException e) { LaunchingPlugin.log(e); } if (!found) { addSourceAttachment(entry, containers); } } }