JdtProjectClasspathExtractor.java
package de.uka.ipd.sdq.beagle.core.facade;
import de.uka.ipd.sdq.beagle.core.failurehandling.FailureHandler;
import de.uka.ipd.sdq.beagle.core.failurehandling.FailureReport;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
/**
* Extracts the class path of an Eclipse Java project.
*
* @author Joshua Gleitze
*/
public class JdtProjectClasspathExtractor {
/**
* Handler of failures.
*/
private static final FailureHandler FAILURE_HANDLER =
FailureHandler.getHandler("Eclipse Java Project Classpath Extractor");
/**
* The project to extract from.
*/
private final IJavaProject project;
/**
* The projects we already evaluated. Used to not extract classpaths of the same
* project multiple times (the same projects may be referenced multiple times by
* different referenced projects).
*/
private final Set<IJavaProject> extractedProjects = new HashSet<>();
/**
* Creates the extractor for the given {@code project}.
*
* @param project The project to extract the class path from.
*/
public JdtProjectClasspathExtractor(final IJavaProject project) {
this.project = project;
}
/**
* Builds a class path string separated by {@link File#pathSeparator} out of the
* project’s class path.
*
* @return the built classpath.
*/
public String getClasspath() {
return StringUtils.join(this.getClasspathEntriesFor(this.project), File.pathSeparator);
}
/**
* Extracts the classpath entries of the given {@code project}.
*
* @param projectToBeExtracted The project to extract the classpath from.
* @return All classpath entries found.
*/
private Set<String> getClasspathEntriesFor(final IJavaProject projectToBeExtracted) {
final IClasspathEntry[] classpathEntries;
this.extractedProjects.add(projectToBeExtracted);
try {
classpathEntries = projectToBeExtracted.getResolvedClasspath(true);
} catch (final JavaModelException retrievalError) {
final FailureReport<Set<String>> failure = new FailureReport<Set<String>>()
.message("Could not get the classpath of the project %s", projectToBeExtracted.getProject().getName())
.cause(retrievalError)
.recoverable()
.retryWith(() -> this.getClasspathEntriesFor(projectToBeExtracted));
return FAILURE_HANDLER.handle(failure);
}
final IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot();
// collect the entries in a set to remove duplicates that might occur when
// resolving multiple projects.
final Set<String> entries = new HashSet<>();
for (final IClasspathEntry classpathEntry : classpathEntries) {
final IPath entryPath = classpathEntry.getPath();
switch (classpathEntry.getEntryKind()) {
case IClasspathEntry.CPE_PROJECT:
final IJavaProject referencedProject = JavaCore.create(workspace.getProject(entryPath.toString()));
if (!this.extractedProjects.contains(referencedProject)) {
entries.addAll(this.getClasspathEntriesFor(referencedProject));
}
break;
default:
// See if the root workspace can resolve the path, if yes, resolve to
// file-system-absolute path.
final IResource pathResource = workspace.findMember(entryPath);
if (pathResource != null) {
entries.add(pathResource.getRawLocation().toOSString());
} else {
entries.add(entryPath.toOSString());
}
}
}
return entries;
}
}