blob: bfd64d55d9e416be5fe05f6e2741048e3579efb8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.launching;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.osgi.util.NLS;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Default Project dependencies entries for a Java project
*/
public class DefaultProjectDependencies extends AbstractRuntimeClasspathEntry {
public static final String TYPE_ID = "org.eclipse.jdt.launching.classpathentry.defaultDependencies"; //$NON-NLS-1$
/**
* Whether only exported entries should be on the runtime classpath.
* By default all entries are on the runtime classpath.
*/
private boolean fExportedEntriesOnly = false;
/**
* Default constructor need to instantiate extensions
*/
public DefaultProjectDependencies() {
setClasspathProperty(IRuntimeClasspathEntry.MODULE_PATH);
}
/**
* Constructs a new classpath entry for the given project.
*
* @param project Java project
*/
public DefaultProjectDependencies(IJavaProject project) {
setJavaProject(project);
setClasspathProperty(IRuntimeClasspathEntry.MODULE_PATH);
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.launching.AbstractRuntimeClasspathEntry#buildMemento(org.w3c.dom.Document, org.w3c.dom.Element)
*/
@Override
protected void buildMemento(Document document, Element memento) throws CoreException {
memento.setAttribute("project", getJavaProject().getElementName()); //$NON-NLS-1$
memento.setAttribute("exportedEntriesOnly", Boolean.toString(fExportedEntriesOnly)); //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#initializeFrom(org.w3c.dom.Element)
*/
@Override
public void initializeFrom(Element memento) throws CoreException {
String name = memento.getAttribute("project"); //$NON-NLS-1$
if (name == null) {
abort(LaunchingMessages.DefaultProjectClasspathEntry_3, null);
}
IJavaProject project = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject(name));
setJavaProject(project);
name = memento.getAttribute("exportedEntriesOnly"); //$NON-NLS-1$
if (name != null) {
fExportedEntriesOnly = Boolean.valueOf(name).booleanValue();
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getTypeId()
*/
@Override
public String getTypeId() {
return TYPE_ID;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getType()
*/
@Override
public int getType() {
return OTHER;
}
protected IProject getProject() {
return getJavaProject().getProject();
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getLocation()
*/
@Override
public String getLocation() {
return getProject().getLocation().toOSString();
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getPath()
*/
@Override
public IPath getPath() {
return getProject().getFullPath();
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getResource()
*/
@Override
public IResource getResource() {
return getProject();
}
public IRuntimeClasspathEntry[] getDefualtDependencies() throws CoreException {
IClasspathEntry entry = JavaCore.newProjectEntry(getJavaProject().getProject().getFullPath());
List<Object> classpathEntries = new ArrayList<>(5);
expandProject(entry, classpathEntries);
IRuntimeClasspathEntry[] runtimeEntries = new IRuntimeClasspathEntry[classpathEntries.size()];
for (int i = 0; i < runtimeEntries.length; i++) {
Object e = classpathEntries.get(i);
if (e instanceof IClasspathEntry) {
IClasspathEntry cpe = (IClasspathEntry) e;
runtimeEntries[i] = new RuntimeClasspathEntry(cpe);
} else {
runtimeEntries[i] = (IRuntimeClasspathEntry) e;
}
}
return runtimeEntries;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getRuntimeClasspathEntries(org.eclipse.debug.core.ILaunchConfiguration)
*/
@Override
public IRuntimeClasspathEntry[] getRuntimeClasspathEntries(ILaunchConfiguration configuration) throws CoreException {
return new IRuntimeClasspathEntry[0];
}
/**
* Returns the transitive closure of classpath entries for the
* given project entry.
*
* @param projectEntry project classpath entry
* @param expandedPath a list of entries already expanded, should be empty
* to begin, and contains the result
* @param expanding a list of projects that have been or are currently being
* expanded (to detect cycles)
* @exception CoreException if unable to expand the classpath
*/
private void expandProject(IClasspathEntry projectEntry, List<Object> expandedPath) throws CoreException {
IPath projectPath = projectEntry.getPath();
IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(projectPath.lastSegment());
if (res == null) {
// add project entry and return
expandedPath.add(projectEntry);
return;
}
IJavaProject project = (IJavaProject)JavaCore.create(res);
if (project == null || !project.getProject().isOpen() || !project.exists()) {
// add project entry and return
expandedPath.add(projectEntry);
return;
}
expandedPath.add(projectEntry);
IClasspathEntry[] buildPath1 = project.getResolvedClasspath(true);
for (IClasspathEntry iClasspathEntry : buildPath1) {
if (iClasspathEntry.getEntryKind() != IClasspathEntry.CPE_SOURCE) {
IRuntimeClasspathEntry r = JavaRuntime.newRuntimeContainerClasspathEntry(iClasspathEntry, project);
expandedPath.add(r);
}
}
return;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#isComposite()
*/
@Override
public boolean isComposite() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getName()
*/
@Override
public String getName() {
if (isExportedEntriesOnly()) {
return NLS.bind(LaunchingMessages.DefaultProjectClasspathEntry_2, new String[] {getJavaProject().getElementName()});
}
return NLS.bind(LaunchingMessages.DefaultProjectClasspathEntry_4, new String[] {getJavaProject().getElementName()});
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof DefaultProjectDependencies) {
DefaultProjectDependencies entry = (DefaultProjectDependencies) obj;
return entry.getJavaProject().equals(getJavaProject()) &&
entry.isExportedEntriesOnly() == isExportedEntriesOnly();
}
return false;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return getJavaProject().hashCode();
}
/**
* Sets whether the runtime classpath computation should only
* include exported entries in referenced projects.
*
* @param exportedOnly if the runtime classpath computation should only
* include exported entries in referenced projects.
* @since 3.2
*/
public void setExportedEntriesOnly(boolean exportedOnly) {
fExportedEntriesOnly = exportedOnly;
}
/**
* Returns whether the classpath computation only includes exported
* entries in referenced projects.
*
* @return if the classpath computation only includes exported
* entries in referenced projects.
* @since 3.2
*/
public boolean isExportedEntriesOnly() {
return fExportedEntriesOnly | Platform.getPreferencesService().getBoolean(
LaunchingPlugin.ID_PLUGIN,
JavaRuntime.PREF_ONLY_INCLUDE_EXPORTED_CLASSPATH_ENTRIES,
false,
null);
}
}