package com.redhat.ceylon.eclipse.core.launch;
import static com.redhat.ceylon.eclipse.util.InteropUtils.toJavaString;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate;
import org.eclipse.debug.core.sourcelookup.containers.ExternalArchiveSourceContainer;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer;
import com.redhat.ceylon.cmr.api.ArtifactContext;
import com.redhat.ceylon.eclipse.core.builder.CeylonBuilder;
import com.redhat.ceylon.ide.common.model.BaseIdeModule;
public class CeylonSourcePathComputer implements ISourcePathComputerDelegate {
@Override
public ISourceContainer[] computeSourceContainers(
ILaunchConfiguration configuration, IProgressMonitor monitor)
throws CoreException {
IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedSourceLookupPath(configuration);
IRuntimeClasspathEntry[] resolved = JavaRuntime.resolveSourceLookupPath(entries, configuration);
List<IRuntimeClasspathEntry> resolvedEntries = new ArrayList<>(resolved.length);
for (IRuntimeClasspathEntry entry : resolved) {
// Don't add the exploded Ceylon classes directory to the source containers !
if (! entry.getPath().lastSegment().equals(CeylonBuilder.CEYLON_CLASSES_FOLDER_NAME)) {
resolvedEntries.add(entry);
}
}
List<ISourceContainer> containers = new ArrayList<ISourceContainer>(resolvedEntries.size());
// When it's a Ceylon CAR archive that has a SRC attachment,
// also add the SRC archive as an archive container not only a PackageFragmentRoot-based container
for (ISourceContainer container : JavaRuntime.getSourceContainers(resolvedEntries.toArray(new IRuntimeClasspathEntry[0]))) {
containers.add(container);
if (container instanceof PackageFragmentRootSourceContainer) {
PackageFragmentRootSourceContainer pfrSourceContainer = (PackageFragmentRootSourceContainer) container;
IPackageFragmentRoot pfr = pfrSourceContainer.getPackageFragmentRoot();
if (pfr != null) {
IPath sourceAttachment = pfr.getSourceAttachmentPath();
if (sourceAttachment != null) {
if (sourceAttachment.lastSegment().endsWith(ArtifactContext.SRC)) {
containers.add(new ExternalArchiveSourceContainer(sourceAttachment.toOSString(), true));
} else if (sourceAttachment.lastSegment().endsWith("javaSources.zip")) {
IJavaProject javaProject = pfr.getJavaProject();
IProject project = javaProject != null ? javaProject.getProject() : null;
Collection<BaseIdeModule> modules = project != null ? CeylonBuilder.getProjectExternalModules(project) : null;
File archiveFile = pfr.getPath().toFile();
if (archiveFile != null
&& modules != null) {
for (BaseIdeModule m : modules) {
if (m.getIsCeylonBinaryArchive()
&& archiveFile.equals(m.getArtifact())) {
String sourceArchivePath = toJavaString(m.getSourceArchivePath());
if (sourceArchivePath != null) {
containers.add(new ExternalArchiveSourceContainer(sourceArchivePath, true));
break;
}
}
}
}
}
}
}
}
}
return containers.toArray(new ISourceContainer[containers.size()]);
}
}