package org.eclipse.jdt.internal.core;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.util.Util;
public class SetContainerOperation extends ChangeClasspathOperation {
IPath containerPath;
IJavaProject[] affectedProjects;
IClasspathContainer[] respectiveContainers;
public SetContainerOperation(IPath containerPath, IJavaProject[] affectedProjects, IClasspathContainer[] respectiveContainers) {
super(new IJavaElement[] {JavaModelManager.getJavaModelManager().getJavaModel()}, !ResourcesPlugin.getWorkspace().isTreeLocked());
this.containerPath = containerPath;
this.affectedProjects = affectedProjects;
this.respectiveContainers = respectiveContainers;
}
@Override
protected void executeOperation() throws JavaModelException {
checkCanceled();
try {
beginTask("", 1);
if (JavaModelManager.CP_RESOLVE_VERBOSE)
verbose_set_container();
if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
verbose_set_container_invocation_trace();
JavaModelManager manager = JavaModelManager.getJavaModelManager();
if (manager.containerPutIfInitializingWithSameEntries(this.containerPath, this.affectedProjects, this.respectiveContainers))
return;
final int projectLength = this.affectedProjects.length;
final IJavaProject[] modifiedProjects;
System.arraycopy(this.affectedProjects, 0, modifiedProjects = new IJavaProject[projectLength], 0, projectLength);
int remaining = 0;
for (int i = 0; i < projectLength; i++){
if (isCanceled())
return;
JavaProject affectedProject = (JavaProject) this.affectedProjects[i];
IClasspathContainer newContainer = this.respectiveContainers[i];
if (newContainer == null) newContainer = JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS;
boolean found = false;
if (JavaProject.hasJavaNature(affectedProject.getProject())){
IClasspathEntry[] rawClasspath = affectedProject.getRawClasspath();
for (int j = 0, cpLength = rawClasspath.length; j <cpLength; j++) {
IClasspathEntry entry = rawClasspath[j];
if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER && entry.getPath().equals(this.containerPath)){
found = true;
break;
}
}
}
if (!found) {
modifiedProjects[i] = null;
manager.containerPut(affectedProject, this.containerPath, newContainer);
continue;
}
IClasspathContainer oldContainer = manager.containerGet(affectedProject, this.containerPath);
if (oldContainer == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
oldContainer = null;
}
if ((oldContainer != null && oldContainer.equals(this.respectiveContainers[i]))
|| (oldContainer == this.respectiveContainers[i])) {
modifiedProjects[i] = null;
continue;
}
remaining++;
manager.containerPut(affectedProject, this.containerPath, newContainer);
}
if (remaining == 0) return;
try {
for(int i = 0; i < projectLength; i++){
this.progressMonitor.setWorkRemaining(projectLength - i);
if (isCanceled())
return;
JavaProject affectedProject = (JavaProject)modifiedProjects[i];
if (affectedProject == null) continue;
if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
verbose_update_project(affectedProject);
ClasspathChange classpathChange = affectedProject.getPerProjectInfo().resetResolvedClasspath();
classpathChanged(classpathChange, i==0);
if (this.canChangeResources) {
try {
affectedProject.getProject().touch(this.progressMonitor.split(1));
} catch (CoreException e) {
if (!ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(affectedProject.getElementName()))
throw e;
}
}
}
} catch(CoreException e) {
if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE)
verbose_failure(e);
if (e instanceof JavaModelException) {
throw (JavaModelException)e;
} else {
throw new JavaModelException(e);
}
} finally {
for (int i = 0; i < projectLength; i++) {
if (this.respectiveContainers[i] == null) {
manager.containerPut(this.affectedProjects[i], this.containerPath, null);
}
}
}
} finally {
done();
}
}
private void verbose_failure(CoreException e) {
Util.verbose(
"CPContainer SET - FAILED DUE TO EXCEPTION\n" +
" container path: " + this.containerPath,
System.err);
e.printStackTrace();
}
private void verbose_update_project(JavaProject affectedProject) {
Util.verbose(
"CPContainer SET - updating affected project due to setting container\n" +
" project: " + affectedProject.getElementName() + '\n' +
" container path: " + this.containerPath);
}
private void verbose_set_container() {
Util.verbose(
"CPContainer SET - setting container\n" +
" container path: " + this.containerPath + '\n' +
" projects: {" +
org.eclipse.jdt.internal.compiler.util.Util.toString(
this.affectedProjects,
new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){
@Override
public String displayString(Object o) { return ((IJavaProject) o).getElementName(); }
}) +
"}\n values: {\n" +
org.eclipse.jdt.internal.compiler.util.Util.toString(
this.respectiveContainers,
new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){
@Override
public String displayString(Object o) {
StringBuffer buffer = new StringBuffer(" ");
if (o == null) {
buffer.append("<null>");
return buffer.toString();
}
IClasspathContainer container = (IClasspathContainer) o;
buffer.append(container.getDescription());
buffer.append(" {\n");
IClasspathEntry[] entries = container.getClasspathEntries();
if (entries != null){
for (int i = 0; i < entries.length; i++){
buffer.append(" ");
buffer.append(entries[i]);
buffer.append('\n');
}
}
buffer.append(" }");
return buffer.toString();
}
}) +
"\n }");
}
private void verbose_set_container_invocation_trace() {
Util.verbose(
"CPContainer SET - setting container\n" +
" invocation stack trace:");
new Exception("<Fake exception>").printStackTrace(System.out);
}
}