IJavaProject
's classpath.
- *
+ *
* @see IJavaProject
*/
public class SetClasspathOperation extends JavaModelOperation {
IClasspathEntry[] oldResolvedPath, newResolvedPath;
+
IClasspathEntry[] newRawPath;
+
boolean canChangeResources;
+
+ boolean classpathWasSaved;
+
boolean needCycleCheck;
+
boolean needValidation;
+
boolean needSave;
+
IPath newOutputLocation;
+
JavaProject project;
+
boolean identicalRoots;
-
+
public static final IClasspathEntry[] ReuseClasspath = new IClasspathEntry[0];
+
public static final IClasspathEntry[] UpdateClasspath = new IClasspathEntry[0];
+
// if reusing output location, then also reuse clean flag
- public static final IPath ReuseOutputLocation = new Path("Reuse Existing Output Location"); //$NON-NLS-1$
-
+ public static final IPath ReuseOutputLocation = new Path(
+ "Reuse Existing Output Location"); //$NON-NLS-1$
+
/**
* When executed, this operation sets the classpath of the given project.
*/
- public SetClasspathOperation(
- JavaProject project,
- IClasspathEntry[] oldResolvedPath,
- IClasspathEntry[] newRawPath,
- IPath newOutputLocation,
- boolean canChangeResource,
- boolean needValidation,
- boolean needSave) {
+ public SetClasspathOperation(JavaProject project,
+ IClasspathEntry[] oldResolvedPath, IClasspathEntry[] newRawPath,
+ IPath newOutputLocation, boolean canChangeResource,
+ boolean needValidation, boolean needSave) {
super(new IJavaElement[] { project });
this.oldResolvedPath = oldResolvedPath;
@@ -87,443 +90,540 @@ public class SetClasspathOperation extends JavaModelOperation {
}
/**
- * Adds deltas for the given roots, with the specified change flag,
- * and closes the root. Helper method for #setClasspath
+ * Adds deltas for the given roots, with the specified change flag, and
+ * closes the root. Helper method for #setClasspath
*/
- protected void addClasspathDeltas(
- IPackageFragmentRoot[] roots,
- int flag,
- JavaElementDelta delta) {
+ protected void addClasspathDeltas(IPackageFragmentRoot[] roots, int flag,
+ JavaElementDelta delta) {
for (int i = 0; i < roots.length; i++) {
IPackageFragmentRoot root = roots[i];
delta.changed(root, flag);
- if ((flag & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0
+ if ((flag & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0
|| (flag & IJavaElementDelta.F_SOURCEATTACHED) != 0
- || (flag & IJavaElementDelta.F_SOURCEDETACHED) != 0){
+ || (flag & IJavaElementDelta.F_SOURCEDETACHED) != 0) {
try {
root.close();
} catch (JavaModelException e) {
}
- // force detach source on jar package fragment roots (source will be lazily computed when needed)
- ((PackageFragmentRoot) root).setSourceAttachmentProperty(null);// loose info - will be recomputed
+ // force detach source on jar package fragment roots (source
+ // will be lazily computed when needed)
+ ((PackageFragmentRoot) root).setSourceAttachmentProperty(null);// loose
+ // info
+ // -
+ // will
+ // be
+ // recomputed
}
}
}
-
-
/**
- * Returns the index of the item in the list if the given list contains the specified entry. If the list does
- * not contain the entry, -1 is returned.
+ * Returns the index of the item in the list if the given list contains the
+ * specified entry. If the list does not contain the entry, -1 is returned.
* A helper method for #setClasspath
*/
- protected int classpathContains(
- IClasspathEntry[] list,
- IClasspathEntry entry) {
+ protected int classpathContains(IClasspathEntry[] list,
+ IClasspathEntry entry) {
IPath[] exclusionPatterns = entry.getExclusionPatterns();
nextEntry: for (int i = 0; i < list.length; i++) {
IClasspathEntry other = list[i];
if (other.getContentKind() == entry.getContentKind()
- && other.getEntryKind() == entry.getEntryKind()
- && other.isExported() == entry.isExported()
- && other.getPath().equals(entry.getPath())) {
- // check custom outputs
- IPath entryOutput = entry.getOutputLocation();
- IPath otherOutput = other.getOutputLocation();
- if (entryOutput == null) {
- if (otherOutput != null)
- continue;
- } else {
- if (!entryOutput.equals(otherOutput))
- continue;
- }
-
- // check exclusion patterns
- IPath[] otherExcludes = other.getExclusionPatterns();
- if (exclusionPatterns != otherExcludes) {
- int excludeLength = exclusionPatterns.length;
- if (otherExcludes.length != excludeLength)
- continue;
- for (int j = 0; j < excludeLength; j++) {
- // compare toStrings instead of IPaths
- // since IPath.equals is specified to ignore trailing separators
- if (!exclusionPatterns[j].toString().equals(otherExcludes[j].toString()))
- continue nextEntry;
- }
+ && other.getEntryKind() == entry.getEntryKind()
+ && other.isExported() == entry.isExported()
+ && other.getPath().equals(entry.getPath())) {
+ // check custom outputs
+ IPath entryOutput = entry.getOutputLocation();
+ IPath otherOutput = other.getOutputLocation();
+ if (entryOutput == null) {
+ if (otherOutput != null)
+ continue;
+ } else {
+ if (!entryOutput.equals(otherOutput))
+ continue;
+ }
+
+ // check exclusion patterns
+ IPath[] otherExcludes = other.getExclusionPatterns();
+ if (exclusionPatterns != otherExcludes) {
+ int excludeLength = exclusionPatterns.length;
+ if (otherExcludes.length != excludeLength)
+ continue;
+ for (int j = 0; j < excludeLength; j++) {
+ // compare toStrings instead of IPaths
+ // since IPath.equals is specified to ignore trailing
+ // separators
+ if (!exclusionPatterns[j].toString().equals(
+ otherExcludes[j].toString()))
+ continue nextEntry;
}
- return i;
+ }
+ return i;
}
}
return -1;
}
/**
- * Recursively adds all subfolders of folder
to the given collection.
+ * Recursively adds all subfolders of folder
to the given
+ * collection.
*/
- protected void collectAllSubfolders(IFolder folder, ArrayList collection) throws JavaModelException {
+ protected void collectAllSubfolders(IFolder folder, ArrayList collection)
+ throws JavaModelException {
try {
- IResource[] members= folder.members();
+ IResource[] members = folder.members();
for (int i = 0, max = members.length; i < max; i++) {
- IResource r= members[i];
+ IResource r = members[i];
if (r.getType() == IResource.FOLDER) {
collection.add(r);
- collectAllSubfolders((IFolder)r, collection);
+ collectAllSubfolders((IFolder) r, collection);
}
- }
+ }
} catch (CoreException e) {
throw new JavaModelException(e);
}
}
/**
- * Returns a collection of package fragments that have been added/removed
- * as the result of changing the output location to/from the given
- * location. The collection is empty if no package fragments are
- * affected.
+ * Returns a collection of package fragments that have been added/removed as
+ * the result of changing the output location to/from the given location.
+ * The collection is empty if no package fragments are affected.
*/
-// protected ArrayList determineAffectedPackageFragments(IPath location) throws JavaModelException {
-// ArrayList fragments = new ArrayList();
-// JavaProject project =getProject();
-//
-// // see if this will cause any package fragments to be affected
-// IWorkspace workspace = ResourcesPlugin.getWorkspace();
-// IResource resource = null;
-// if (location != null) {
-// resource = workspace.getRoot().findMember(location);
-// }
-// if (resource != null && resource.getType() == IResource.FOLDER) {
-// IFolder folder = (IFolder) resource;
-// // only changes if it actually existed
-// IClasspathEntry[] classpath = project.getExpandedClasspath(true);
-// for (int i = 0; i < classpath.length; i++) {
-// IClasspathEntry entry = classpath[i];
-// IPath path = classpath[i].getPath();
-// if (entry.getEntryKind() != IClasspathEntry.CPE_PROJECT && path.isPrefixOf(location) && !path.equals(location)) {
-// IPackageFragmentRoot[] roots = project.computePackageFragmentRoots(classpath[i]);
-// IPackageFragmentRoot root = roots[0];
-// // now the output location becomes a package fragment - along with any subfolders
-// ArrayList folders = new ArrayList();
-// folders.add(folder);
-// collectAllSubfolders(folder, folders);
-// Iterator elements = folders.iterator();
-// int segments = path.segmentCount();
-// while (elements.hasNext()) {
-// IFolder f = (IFolder) elements.next();
-// IPath relativePath = f.getFullPath().removeFirstSegments(segments);
-// String name = relativePath.toOSString();
-// name = name.replace(File.pathSeparatorChar, '.');
-// if (name.endsWith(".")) { //$NON-NLS-1$
-// name = name.substring(0, name.length() - 1);
-// }
-// IPackageFragment pkg = root.getPackageFragment(name);
-// fragments.add(pkg);
-// }
-// }
-// }
-// }
-// return fragments;
-// }
+ // protected ArrayList determineAffectedPackageFragments(IPath location)
+ // throws JavaModelException {
+ // ArrayList fragments = new ArrayList();
+ // JavaProject project =getProject();
+ //
+ // // see if this will cause any package fragments to be affected
+ // IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ // IResource resource = null;
+ // if (location != null) {
+ // resource = workspace.getRoot().findMember(location);
+ // }
+ // if (resource != null && resource.getType() == IResource.FOLDER) {
+ // IFolder folder = (IFolder) resource;
+ // // only changes if it actually existed
+ // IClasspathEntry[] classpath = project.getExpandedClasspath(true);
+ // for (int i = 0; i < classpath.length; i++) {
+ // IClasspathEntry entry = classpath[i];
+ // IPath path = classpath[i].getPath();
+ // if (entry.getEntryKind() != IClasspathEntry.CPE_PROJECT &&
+ // path.isPrefixOf(location) && !path.equals(location)) {
+ // IPackageFragmentRoot[] roots =
+ // project.computePackageFragmentRoots(classpath[i]);
+ // IPackageFragmentRoot root = roots[0];
+ // // now the output location becomes a package fragment - along with any
+ // subfolders
+ // ArrayList folders = new ArrayList();
+ // folders.add(folder);
+ // collectAllSubfolders(folder, folders);
+ // Iterator elements = folders.iterator();
+ // int segments = path.segmentCount();
+ // while (elements.hasNext()) {
+ // IFolder f = (IFolder) elements.next();
+ // IPath relativePath = f.getFullPath().removeFirstSegments(segments);
+ // String name = relativePath.toOSString();
+ // name = name.replace(File.pathSeparatorChar, '.');
+ // if (name.endsWith(".")) { //$NON-NLS-1$
+ // name = name.substring(0, name.length() - 1);
+ // }
+ // IPackageFragment pkg = root.getPackageFragment(name);
+ // fragments.add(pkg);
+ // }
+ // }
+ // }
+ // }
+ // return fragments;
+ // }
/**
* Sets the classpath of the pre-specified project.
*/
protected void executeOperation() throws JavaModelException {
- // project reference updated - may throw an exception if unable to write .project file
+ // project reference updated - may throw an exception if unable to write
+ // .project file
updateProjectReferencesIfNecessary();
- // classpath file updated - may throw an exception if unable to write .classpath file
+ // classpath file updated - may throw an exception if unable to write
+ // .classpath file
saveClasspathIfNecessary();
-
- // perform classpath and output location updates, if exception occurs in classpath update,
- // make sure the output location is updated before surfacing the exception (in case the output
- // location update also throws an exception, give priority to the classpath update one).
+
+ // perform classpath and output location updates, if exception occurs in
+ // classpath update,
+ // make sure the output location is updated before surfacing the
+ // exception (in case the output
+ // location update also throws an exception, give priority to the
+ // classpath update one).
JavaModelException originalException = null;
try {
- if (this.newRawPath == UpdateClasspath) this.newRawPath = project.getRawClasspath();
- if (this.newRawPath != ReuseClasspath){
+ if (this.newRawPath == UpdateClasspath)
+ this.newRawPath = project.getRawClasspath();
+ if (this.newRawPath != ReuseClasspath) {
updateClasspath();
project.updatePackageFragmentRoots();
- JavaModelManager.getJavaModelManager().getDeltaProcessor().addForRefresh(project);
+ JavaModelManager.getJavaModelManager().getDeltaProcessor()
+ .addForRefresh(project);
}
- } catch(JavaModelException e){
+ } catch (JavaModelException e) {
originalException = e;
throw e;
- } finally { // if traversed by an exception we still need to update the output location when necessary
+ } finally { // if traversed by an exception we still need to update the
+ // output location when necessary
try {
- if (this.newOutputLocation != ReuseOutputLocation) updateOutputLocation();
+ if (this.newOutputLocation != ReuseOutputLocation)
+ updateOutputLocation();
- } catch(JavaModelException e){
- if (originalException != null) throw originalException;
+ } catch (JavaModelException e) {
+ if (originalException != null)
+ throw originalException;
throw e;
} finally {
- // ensures the project is getting rebuilt if only variable is modified
+ // ensures the project is getting rebuilt if only variable is
+ // modified
if (!this.identicalRoots && this.canChangeResources) {
try {
this.project.getProject().touch(this.progressMonitor);
} catch (CoreException e) {
- if (JavaModelManager.CP_RESOLVE_VERBOSE){
- Util.verbose("CPContainer INIT - FAILED to touch project: "+ this.project.getElementName(), System.err); //$NON-NLS-1$
+ if (JavaModelManager.CP_RESOLVE_VERBOSE) {
+ Util
+ .verbose(
+ "CPContainer INIT - FAILED to touch project: " + this.project.getElementName(), System.err); //$NON-NLS-1$
e.printStackTrace();
}
}
- }
+ }
}
}
done();
}
-
+
/**
- * Generates the delta of removed/added/reordered roots.
- * Use three deltas in case the same root is removed/added/reordered (for
- * instance, if it is changed from K_SOURCE to K_BINARY or vice versa)
+ * Generates the delta of removed/added/reordered roots. Use three deltas in
+ * case the same root is removed/added/reordered (for instance, if it is
+ * changed from K_SOURCE to K_BINARY or vice versa)
*/
-// protected void generateClasspathChangeDeltas(
-// IClasspathEntry[] oldResolvedPath,
-// IClasspathEntry[] newResolvedPath,
-// final JavaProject project) {
-//
-// JavaModelManager manager = JavaModelManager.getJavaModelManager();
-// boolean needToUpdateDependents = false;
-// JavaElementDelta delta = new JavaElementDelta(getJavaModel());
-// boolean hasDelta = false;
-// int oldLength = oldResolvedPath.length;
-// int newLength = newResolvedPath.length;
-//
-// final IndexManager indexManager = manager.getIndexManager();
-// Map oldRoots = null;
-// IPackageFragmentRoot[] roots = null;
-// if (project.isOpen()) {
-// try {
-// roots = project.getPackageFragmentRoots();
-// } catch (JavaModelException e) {
-// }
-// } else {
-// Map allRemovedRoots ;
-// if ((allRemovedRoots = manager.deltaProcessor.removedRoots) != null) {
-// roots = (IPackageFragmentRoot[]) allRemovedRoots.get(project);
-// }
-// }
-// if (roots != null) {
-// oldRoots = new HashMap();
-// for (int i = 0; i < roots.length; i++) {
-// IPackageFragmentRoot root = roots[i];
-// oldRoots.put(root.getPath(), root);
-// }
-// }
-// for (int i = 0; i < oldLength; i++) {
-//
-// int index = classpathContains(newResolvedPath, oldResolvedPath[i]);
-// if (index == -1) {
-// // do not notify remote project changes
-// if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
-// needToUpdateDependents = true;
-// this.needCycleCheck = true;
-// continue;
-// }
-//
-// IPackageFragmentRoot[] pkgFragmentRoots = null;
-// if (oldRoots != null) {
-// IPackageFragmentRoot oldRoot = (IPackageFragmentRoot) oldRoots.get(oldResolvedPath[i].getPath());
-// if (oldRoot != null) { // use old root if any (could be none if entry wasn't bound)
-// pkgFragmentRoots = new IPackageFragmentRoot[] { oldRoot };
-// }
-// }
-// if (pkgFragmentRoots == null) {
-// try {
-// ObjectVector accumulatedRoots = new ObjectVector();
-// HashSet rootIDs = new HashSet(5);
-// rootIDs.add(project.rootID());
-// project.computePackageFragmentRoots(
-// oldResolvedPath[i],
-// accumulatedRoots,
-// rootIDs,
-// true, // inside original project
-// false, // don't check existency
-// false); // don't retrieve exported roots
-// pkgFragmentRoots = new IPackageFragmentRoot[accumulatedRoots.size()];
-// accumulatedRoots.copyInto(pkgFragmentRoots);
-// } catch (JavaModelException e) {
-// pkgFragmentRoots = new IPackageFragmentRoot[] {};
-// }
-// }
-// addClasspathDeltas(pkgFragmentRoots, IJavaElementDelta.F_REMOVED_FROM_CLASSPATH, delta);
-//
-// int changeKind = oldResolvedPath[i].getEntryKind();
-// needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE) || oldResolvedPath[i].isExported();
-//
-// // Remove the .java files from the index for a source folder
-// // For a lib folder or a .jar file, remove the corresponding index if not shared.
-// if (indexManager != null) {
-// IClasspathEntry oldEntry = oldResolvedPath[i];
-// final IPath path = oldEntry.getPath();
-// switch (changeKind) {
-// case IClasspathEntry.CPE_SOURCE:
-// final char[][] exclusionPatterns = ((ClasspathEntry)oldEntry).fullExclusionPatternChars();
-// postAction(new IPostAction() {
-// public String getID() {
-// return path.toString();
-// }
-// public void run() throws JavaModelException {
-// indexManager.removeSourceFolderFromIndex(project, path, exclusionPatterns);
-// }
-// },
-// REMOVEALL_APPEND);
-// break;
-// case IClasspathEntry.CPE_LIBRARY:
-// final DeltaProcessor deltaProcessor = manager.deltaProcessor;
-// postAction(new IPostAction() {
-// public String getID() {
-// return path.toString();
-// }
-// public void run() throws JavaModelException {
-// if (deltaProcessor.otherRoots.get(path) == null) { // if root was not shared
-// indexManager.discardJobs(path.toString());
-// indexManager.removeIndex(path);
-// // TODO: we could just remove the in-memory index and have the indexing check for timestamps
-// }
-// }
-// },
-// REMOVEALL_APPEND);
-// break;
-// }
-// }
-// hasDelta = true;
-//
-// } else {
-// // do not notify remote project changes
-// if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
-// this.needCycleCheck |= (oldResolvedPath[i].isExported() != newResolvedPath[index].isExported());
-// continue;
-// }
-// needToUpdateDependents |= (oldResolvedPath[i].isExported() != newResolvedPath[index].isExported());
-// if (index != i) { //reordering of the classpath
-// addClasspathDeltas(
-// project.computePackageFragmentRoots(oldResolvedPath[i]),
-// IJavaElementDelta.F_REORDER,
-// delta);
-// int changeKind = oldResolvedPath[i].getEntryKind();
-// needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE);
-//
-// hasDelta = true;
-// }
-//
-// // check source attachment
-// IPath newSourcePath = newResolvedPath[index].getSourceAttachmentPath();
-// int sourceAttachmentFlags =
-// this.getSourceAttachmentDeltaFlag(
-// oldResolvedPath[i].getSourceAttachmentPath(),
-// newSourcePath,
-// null/*not a source root path*/);
-// int sourceAttachmentRootFlags =
-// this.getSourceAttachmentDeltaFlag(
-// oldResolvedPath[i].getSourceAttachmentRootPath(),
-// newResolvedPath[index].getSourceAttachmentRootPath(),
-// newSourcePath/*in case both root paths are null*/);
-// int flags = sourceAttachmentFlags | sourceAttachmentRootFlags;
-// if (flags != 0) {
-// addClasspathDeltas(
-// project.computePackageFragmentRoots(oldResolvedPath[i]),
-// flags,
-// delta);
-// hasDelta = true;
-// }
-// }
-// }
-//
-// for (int i = 0; i < newLength; i++) {
-//
-// int index = classpathContains(oldResolvedPath, newResolvedPath[i]);
-// if (index == -1) {
-// // do not notify remote project changes
-// if (newResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
-// needToUpdateDependents = true;
-// this.needCycleCheck = true;
-// continue;
-// }
-// addClasspathDeltas(
-// project.computePackageFragmentRoots(newResolvedPath[i]),
-// IJavaElementDelta.F_ADDED_TO_CLASSPATH,
-// delta);
-// int changeKind = newResolvedPath[i].getEntryKind();
-//
-// // Request indexing
-// if (indexManager != null) {
-// switch (changeKind) {
-// case IClasspathEntry.CPE_LIBRARY:
-// boolean pathHasChanged = true;
-// final IPath newPath = newResolvedPath[i].getPath();
-// for (int j = 0; j < oldLength; j++) {
-// IClasspathEntry oldEntry = oldResolvedPath[j];
-// if (oldEntry.getPath().equals(newPath)) {
-// pathHasChanged = false;
-// break;
-// }
-// }
-// if (pathHasChanged) {
-// postAction(new IPostAction() {
-// public String getID() {
-// return newPath.toString();
-// }
-// public void run() throws JavaModelException {
-// indexManager.indexLibrary(newPath, project.getProject());
-// }
-// },
-// REMOVEALL_APPEND);
-// }
-// break;
-// case IClasspathEntry.CPE_SOURCE:
-// IClasspathEntry entry = newResolvedPath[i];
-// final IPath path = entry.getPath();
-// final char[][] exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
-// postAction(new IPostAction() {
-// public String getID() {
-// return path.toString();
-// }
-// public void run() throws JavaModelException {
-// indexManager.indexSourceFolder(project, path, exclusionPatterns);
-// }
-// },
-// APPEND); // append so that a removeSourceFolder action is not removed
-// break;
-// }
-// }
-//
-// needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE) || newResolvedPath[i].isExported();
-// hasDelta = true;
-//
-// } // classpath reordering has already been generated in previous loop
-// }
-//
-// if (hasDelta) {
-// this.addDelta(delta);
-// }
-// if (needToUpdateDependents){
-// updateAffectedProjects(project.getProject().getFullPath());
-// }
-// }
+ protected void generateClasspathChangeDeltas() {
+
+ JavaModelManager manager = JavaModelManager.getJavaModelManager();
+ boolean needToUpdateDependents = false;
+ JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+ boolean hasDelta = false;
+ if (this.classpathWasSaved) {
+ delta.changed(this.project, IJavaElementDelta.F_CLASSPATH_CHANGED);
+ hasDelta = true;
+ }
+ int oldLength = oldResolvedPath.length;
+ int newLength = newResolvedPath.length;
+
+ // final IndexManager indexManager = manager.getIndexManager();
+ Map oldRoots = null;
+ IPackageFragmentRoot[] roots = null;
+ if (project.isOpen()) {
+ try {
+ roots = project.getPackageFragmentRoots();
+ } catch (JavaModelException e) {
+ // ignore
+ }
+ } else {
+ Map allRemovedRoots;
+ if ((allRemovedRoots = manager.getDeltaProcessor().removedRoots) != null) {
+ roots = (IPackageFragmentRoot[]) allRemovedRoots.get(project);
+ }
+ }
+ if (roots != null) {
+ oldRoots = new HashMap();
+ for (int i = 0; i < roots.length; i++) {
+ IPackageFragmentRoot root = roots[i];
+ oldRoots.put(root.getPath(), root);
+ }
+ }
+ for (int i = 0; i < oldLength; i++) {
+
+ int index = classpathContains(newResolvedPath, oldResolvedPath[i]);
+ if (index == -1) {
+ // do not notify remote project changes
+ if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+ needToUpdateDependents = true;
+ this.needCycleCheck = true;
+ continue;
+ }
+
+ IPackageFragmentRoot[] pkgFragmentRoots = null;
+ if (oldRoots != null) {
+ IPackageFragmentRoot oldRoot = (IPackageFragmentRoot) oldRoots
+ .get(oldResolvedPath[i].getPath());
+ if (oldRoot != null) { // use old root if any (could be
+ // none if entry wasn't bound)
+ pkgFragmentRoots = new IPackageFragmentRoot[] { oldRoot };
+ }
+ }
+ if (pkgFragmentRoots == null) {
+ try {
+ ObjectVector accumulatedRoots = new ObjectVector();
+ HashSet rootIDs = new HashSet(5);
+ rootIDs.add(project.rootID());
+ project.computePackageFragmentRoots(oldResolvedPath[i],
+ accumulatedRoots, rootIDs, true, // inside
+ // original
+ // project
+ false, // don't check existency
+ false); // don't retrieve exported roots
+ pkgFragmentRoots = new IPackageFragmentRoot[accumulatedRoots
+ .size()];
+ accumulatedRoots.copyInto(pkgFragmentRoots);
+ } catch (JavaModelException e) {
+ pkgFragmentRoots = new IPackageFragmentRoot[] {};
+ }
+ }
+ addClasspathDeltas(pkgFragmentRoots,
+ IJavaElementDelta.F_REMOVED_FROM_CLASSPATH, delta);
+
+ int changeKind = oldResolvedPath[i].getEntryKind();
+ needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE)
+ || oldResolvedPath[i].isExported();
+
+ // Remove the .java files from the index for a source folder
+ // For a lib folder or a .jar file, remove the corresponding
+ // index if not shared.
+ // if (indexManager != null) {
+ // IClasspathEntry oldEntry = oldResolvedPath[i];
+ // final IPath path = oldEntry.getPath();
+ // switch (changeKind) {
+ // case IClasspathEntry.CPE_SOURCE:
+ // final char[][] inclusionPatterns = null;
+ // //((ClasspathEntry)oldEntry).fullInclusionPatternChars();
+ // final char[][] exclusionPatterns =
+ // ((ClasspathEntry)oldEntry).fullExclusionPatternChars();
+ // postAction(new IPostAction() {
+ // public String getID() {
+ // return path.toString();
+ // }
+ // public void run() /* throws JavaModelException */ {
+ // indexManager.removeSourceFolderFromIndex(project, path,
+ // inclusionPatterns, exclusionPatterns);
+ // }
+ // },
+ // REMOVEALL_APPEND);
+ // break;
+ // case IClasspathEntry.CPE_LIBRARY:
+ // final DeltaProcessingState deltaState = manager.deltaState;
+ // postAction(new IPostAction() {
+ // public String getID() {
+ // return path.toString();
+ // }
+ // public void run() /* throws JavaModelException */ {
+ // if (deltaState.otherRoots.get(path) == null) { // if root was
+ // not shared
+ // indexManager.discardJobs(path.toString());
+ // indexManager.removeIndex(path);
+ // // TODO (kent) we could just remove the in-memory index and
+ // have the indexing check for timestamps
+ // }
+ // }
+ // },
+ // REMOVEALL_APPEND);
+ // break;
+ // }
+ // }
+ hasDelta = true;
+
+ } else {
+ // do not notify remote project changes
+ if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+ this.needCycleCheck |= (oldResolvedPath[i].isExported() != newResolvedPath[index]
+ .isExported());
+ continue;
+ }
+ needToUpdateDependents |= (oldResolvedPath[i].isExported() != newResolvedPath[index]
+ .isExported());
+ if (index != i) { // reordering of the classpath
+ addClasspathDeltas(project
+ .computePackageFragmentRoots(oldResolvedPath[i]),
+ IJavaElementDelta.F_REORDER, delta);
+ int changeKind = oldResolvedPath[i].getEntryKind();
+ needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE);
+
+ hasDelta = true;
+ }
+
+ // check source attachment
+ IPath newSourcePath = newResolvedPath[index]
+ .getSourceAttachmentPath();
+ int sourceAttachmentFlags = this.getSourceAttachmentDeltaFlag(
+ oldResolvedPath[i].getSourceAttachmentPath(),
+ newSourcePath);
+ IPath oldRootPath = oldResolvedPath[i]
+ .getSourceAttachmentRootPath();
+ IPath newRootPath = newResolvedPath[index]
+ .getSourceAttachmentRootPath();
+ int sourceAttachmentRootFlags = getSourceAttachmentDeltaFlag(
+ oldRootPath, newRootPath);
+ int flags = sourceAttachmentFlags | sourceAttachmentRootFlags;
+ if (flags != 0) {
+ addClasspathDeltas(project
+ .computePackageFragmentRoots(oldResolvedPath[i]),
+ flags, delta);
+ hasDelta = true;
+ } else {
+ if (oldRootPath == null && newRootPath == null) {
+ // if source path is specified and no root path, it
+ // needs to be recomputed dynamically
+ // force detach source on jar package fragment roots
+ // (source will be lazily computed when needed)
+ IPackageFragmentRoot[] computedRoots = project
+ .computePackageFragmentRoots(oldResolvedPath[i]);
+ for (int j = 0; j < computedRoots.length; j++) {
+ IPackageFragmentRoot root = computedRoots[j];
+ // force detach source on jar package fragment roots
+ // (source will be lazily computed when needed)
+ try {
+ root.close();
+ } catch (JavaModelException e) {
+ // ignore
+ }
+ ((PackageFragmentRoot) root)
+ .setSourceAttachmentProperty(null);// loose
+ // info
+ // -
+ // will
+ // be
+ // recomputed
+ }
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < newLength; i++) {
+
+ int index = classpathContains(oldResolvedPath, newResolvedPath[i]);
+ if (index == -1) {
+ // do not notify remote project changes
+ if (newResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+ needToUpdateDependents = true;
+ this.needCycleCheck = true;
+ continue;
+ }
+ addClasspathDeltas(project
+ .computePackageFragmentRoots(newResolvedPath[i]),
+ IJavaElementDelta.F_ADDED_TO_CLASSPATH, delta);
+ int changeKind = newResolvedPath[i].getEntryKind();
+
+ // Request indexing
+ // if (indexManager != null) {
+ // switch (changeKind) {
+ // case IClasspathEntry.CPE_LIBRARY:
+ // boolean pathHasChanged = true;
+ // final IPath newPath = newResolvedPath[i].getPath();
+ // for (int j = 0; j < oldLength; j++) {
+ // IClasspathEntry oldEntry = oldResolvedPath[j];
+ // if (oldEntry.getPath().equals(newPath)) {
+ // pathHasChanged = false;
+ // break;
+ // }
+ // }
+ // if (pathHasChanged) {
+ // postAction(new IPostAction() {
+ // public String getID() {
+ // return newPath.toString();
+ // }
+ // public void run() /* throws JavaModelException */ {
+ // indexManager.indexLibrary(newPath, project.getProject());
+ // }
+ // },
+ // REMOVEALL_APPEND);
+ // }
+ // break;
+ // case IClasspathEntry.CPE_SOURCE:
+ // IClasspathEntry entry = newResolvedPath[i];
+ // final IPath path = entry.getPath();
+ // final char[][] inclusionPatterns = null;
+ // //((ClasspathEntry)entry).fullInclusionPatternChars();
+ // final char[][] exclusionPatterns =
+ // ((ClasspathEntry)entry).fullExclusionPatternChars();
+ // postAction(new IPostAction() {
+ // public String getID() {
+ // return path.toString();
+ // }
+ // public void run() /* throws JavaModelException */ {
+ // indexManager.indexSourceFolder(project, path,
+ // inclusionPatterns, exclusionPatterns);
+ // }
+ // },
+ // APPEND); // append so that a removeSourceFolder action is not
+ // removed
+ // break;
+ // }
+ // }
+
+ needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE)
+ || newResolvedPath[i].isExported();
+ hasDelta = true;
+
+ } // classpath reordering has already been generated in previous
+ // loop
+ }
+
+ if (hasDelta) {
+ this.addDelta(delta);
+ } else {
+ this.identicalRoots = true;
+ }
+ if (needToUpdateDependents) {
+ updateAffectedProjects(project.getProject().getFullPath());
+ }
+ }
+
+ protected void saveClasspathIfNecessary() throws JavaModelException {
+
+ if (!this.canChangeResources || !this.needSave)
+ return;
+
+ IClasspathEntry[] classpathForSave;
+ if (this.newRawPath == ReuseClasspath
+ || this.newRawPath == UpdateClasspath) {
+ classpathForSave = project.getRawClasspath();
+ } else {
+ classpathForSave = this.newRawPath;
+ }
+ IPath outputLocationForSave;
+ if (this.newOutputLocation == ReuseOutputLocation) {
+ outputLocationForSave = project.getOutputLocation();
+ } else {
+ outputLocationForSave = this.newOutputLocation;
+ }
+ // if read-only .classpath, then the classpath setting will never been
+ // performed completely
+ if (project.saveClasspath(classpathForSave, outputLocationForSave)) {
+ this.classpathWasSaved = true;
+ this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+ }
+ }
protected JavaProject getProject() {
return ((JavaProject) getElementsToProcess()[0]);
}
/*
- * Returns the source attachment flag for the delta between the 2 give source paths.
- * Returns either F_SOURCEATTACHED, F_SOURCEDETACHED, F_SOURCEATTACHED | F_SOURCEDETACHED
- * or 0 if there is no difference.
+ * Returns the source attachment flag for the delta between the 2 give
+ * source paths. Returns either F_SOURCEATTACHED, F_SOURCEDETACHED,
+ * F_SOURCEATTACHED | F_SOURCEDETACHED or 0 if there is no difference.
*/
- private int getSourceAttachmentDeltaFlag(IPath oldPath, IPath newPath, IPath sourcePath) {
+ private int getSourceAttachmentDeltaFlag(IPath oldPath, IPath newPath,
+ IPath sourcePath) {
if (oldPath == null) {
if (newPath != null) {
return IJavaElementDelta.F_SOURCEATTACHED;
} else {
if (sourcePath != null) {
- // if source path is specified and no root path, it needs to be recomputed dynamically
- return IJavaElementDelta.F_SOURCEATTACHED | IJavaElementDelta.F_SOURCEDETACHED;
+ // if source path is specified and no root path, it needs to
+ // be recomputed dynamically
+ return IJavaElementDelta.F_SOURCEATTACHED
+ | IJavaElementDelta.F_SOURCEDETACHED;
} else {
return 0;
}
@@ -531,59 +631,85 @@ public class SetClasspathOperation extends JavaModelOperation {
} else if (newPath == null) {
return IJavaElementDelta.F_SOURCEDETACHED;
} else if (!oldPath.equals(newPath)) {
- return IJavaElementDelta.F_SOURCEATTACHED | IJavaElementDelta.F_SOURCEDETACHED;
+ return IJavaElementDelta.F_SOURCEATTACHED
+ | IJavaElementDelta.F_SOURCEDETACHED;
+ } else {
+ return 0;
+ }
+ }
+
+ /*
+ * Returns the source attachment flag for the delta between the 2 give
+ * source paths. Returns either F_SOURCEATTACHED, F_SOURCEDETACHED,
+ * F_SOURCEATTACHED | F_SOURCEDETACHED or 0 if there is no difference.
+ */
+ private int getSourceAttachmentDeltaFlag(IPath oldPath, IPath newPath) {
+ if (oldPath == null) {
+ if (newPath != null) {
+ return IJavaElementDelta.F_SOURCEATTACHED;
+ } else {
+ return 0;
+ }
+ } else if (newPath == null) {
+ return IJavaElementDelta.F_SOURCEDETACHED;
+ } else if (!oldPath.equals(newPath)) {
+ return IJavaElementDelta.F_SOURCEATTACHED
+ | IJavaElementDelta.F_SOURCEDETACHED;
} else {
return 0;
}
}
/**
- * Returns true
if this operation performs no resource modifications,
- * otherwise false
. Subclasses must override.
+ * Returns true
if this operation performs no resource
+ * modifications, otherwise false
. Subclasses must override.
*/
public boolean isReadOnly() {
return !this.canChangeResources;
}
- protected void saveClasspathIfNecessary() throws JavaModelException {
-
- if (!this.canChangeResources || !this.needSave) return;
-
- IClasspathEntry[] classpathForSave;
- JavaProject project = getProject();
- if (this.newRawPath == ReuseClasspath || this.newRawPath == UpdateClasspath){
- classpathForSave = project.getRawClasspath();
- } else {
- classpathForSave = this.newRawPath;
- }
- IPath outputLocationForSave;
- if (this.newOutputLocation == ReuseOutputLocation){
- outputLocationForSave = project.getOutputLocation();
- } else {
- outputLocationForSave = this.newOutputLocation;
- }
- // if read-only .classpath, then the classpath setting will never been performed completely
- if (project.saveClasspath(classpathForSave, outputLocationForSave)) {
- this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
- }
- }
-
- public String toString(){
+ // protected void saveClasspathIfNecessary() throws JavaModelException {
+ //
+ // if (!this.canChangeResources || !this.needSave) return;
+ //
+ // IClasspathEntry[] classpathForSave;
+ // JavaProject project = getProject();
+ // if (this.newRawPath == ReuseClasspath || this.newRawPath ==
+ // UpdateClasspath){
+ // classpathForSave = project.getRawClasspath();
+ // } else {
+ // classpathForSave = this.newRawPath;
+ // }
+ // IPath outputLocationForSave;
+ // if (this.newOutputLocation == ReuseOutputLocation){
+ // outputLocationForSave = project.getOutputLocation();
+ // } else {
+ // outputLocationForSave = this.newOutputLocation;
+ // }
+ // // if read-only .classpath, then the classpath setting will never been
+ // performed completely
+ // if (project.saveClasspath(classpathForSave, outputLocationForSave)) {
+ // this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+ // }
+ // }
+
+ public String toString() {
StringBuffer buffer = new StringBuffer(20);
buffer.append("SetClasspathOperation\n"); //$NON-NLS-1$
buffer.append(" - classpath : "); //$NON-NLS-1$
- if (this.newRawPath == ReuseClasspath){
+ if (this.newRawPath == ReuseClasspath) {
buffer.append("This can cause changes in package fragments, in case either the - * old or new output location folder are considered as a package fragment. + * + *
+ * This can cause changes in package fragments, in case either the old or + * new output location folder are considered as a package fragment. */ protected void updateOutputLocation() throws JavaModelException { - - JavaProject project= ((JavaProject) getElementsToProcess()[0]); - beginTask(Util.bind("classpath.settingOutputLocationProgress", project.getElementName()), 2); //$NON-NLS-1$ - - IPath oldLocation= project.getOutputLocation(); - + JavaProject project = ((JavaProject) getElementsToProcess()[0]); + + beginTask( + Util + .bind( + "classpath.settingOutputLocationProgress", project.getElementName()), 2); //$NON-NLS-1$ + + IPath oldLocation = project.getOutputLocation(); + // see if this will cause any package fragments to be added - boolean deltaToFire= false; + boolean deltaToFire = false; JavaElementDelta delta = newJavaElementDelta(); -// ArrayList added= determineAffectedPackageFragments(oldLocation); -// Iterator iter = added.iterator(); -// while (iter.hasNext()){ -// IPackageFragment frag= (IPackageFragment)iter.next(); -// ((IPackageFragmentRoot)frag.getParent()).close(); -// if (!Util.isExcluded(frag)) { -// delta.added(frag); -// deltaToFire = true; -// } -// } - + // ArrayList added= determineAffectedPackageFragments(oldLocation); + // Iterator iter = added.iterator(); + // while (iter.hasNext()){ + // IPackageFragment frag= (IPackageFragment)iter.next(); + // ((IPackageFragmentRoot)frag.getParent()).close(); + // if (!ProjectPrefUtil.isExcluded(frag)) { + // delta.added(frag); + // deltaToFire = true; + // } + // } + // see if this will cause any package fragments to be removed -// ArrayList removed= determineAffectedPackageFragments(this.newOutputLocation); -// iter = removed.iterator(); -// while (iter.hasNext()){ -// IPackageFragment frag= (IPackageFragment)iter.next(); -// ((IPackageFragmentRoot)frag.getParent()).close(); -// if (!Util.isExcluded(frag)) { -// delta.removed(frag); -// deltaToFire = true; -// } -// } - - JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject()); + // ArrayList removed= + // determineAffectedPackageFragments(this.newOutputLocation); + // iter = removed.iterator(); + // while (iter.hasNext()){ + // IPackageFragment frag= (IPackageFragment)iter.next(); + // ((IPackageFragmentRoot)frag.getParent()).close(); + // if (!ProjectPrefUtil.isExcluded(frag)) { + // delta.removed(frag); + // deltaToFire = true; + // } + // } + + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager + .getJavaModelManager().getPerProjectInfoCheckExistence( + project.getProject()); synchronized (perProjectInfo) { perProjectInfo.outputLocation = this.newOutputLocation; } - + if (deltaToFire) { - addDelta(delta); + addDelta(delta); } worked(1); } - + /** - * Update projects references so that the build order is consistent with the classpath + * Update projects references so that the build order is consistent with the + * classpath */ - protected void updateProjectReferencesIfNecessary() throws JavaModelException { - - if (!this.canChangeResources) return; - if (this.newRawPath == ReuseClasspath || this.newRawPath == UpdateClasspath) return; - + protected void updateProjectReferencesIfNecessary() + throws JavaModelException { + + if (!this.canChangeResources) + return; + if (this.newRawPath == ReuseClasspath + || this.newRawPath == UpdateClasspath) + return; + JavaProject jproject = getProject(); - String[] oldRequired = jproject.projectPrerequisites(this.oldResolvedPath); + String[] oldRequired = jproject + .projectPrerequisites(this.oldResolvedPath); if (this.newResolvedPath == null) { - this.newResolvedPath = jproject.getResolvedClasspath(this.newRawPath, null, true, this.needValidation, null /*no reverse map*/); + this.newResolvedPath = jproject + .getResolvedClasspath(this.newRawPath, null, true, + this.needValidation, null /* no reverse map */); } - String[] newRequired = jproject.projectPrerequisites(this.newResolvedPath); - - try { + String[] newRequired = jproject + .projectPrerequisites(this.newResolvedPath); + + try { IProject project = jproject.getProject(); IProjectDescription description = project.getDescription(); - + IProject[] projectReferences = description.getReferencedProjects(); - + HashSet oldReferences = new HashSet(projectReferences.length); - for (int i = 0; i < projectReferences.length; i++){ + for (int i = 0; i < projectReferences.length; i++) { String projectName = projectReferences[i].getName(); oldReferences.add(projectName); } - HashSet newReferences = (HashSet)oldReferences.clone(); - - for (int i = 0; i < oldRequired.length; i++){ + HashSet newReferences = (HashSet) oldReferences.clone(); + + for (int i = 0; i < oldRequired.length; i++) { String projectName = oldRequired[i]; newReferences.remove(projectName); } - for (int i = 0; i < newRequired.length; i++){ + for (int i = 0; i < newRequired.length; i++) { String projectName = newRequired[i]; newReferences.add(projectName); } - + Iterator iter; int newSize = newReferences.size(); - + checkIdentity: { - if (oldReferences.size() == newSize){ + if (oldReferences.size() == newSize) { iter = newReferences.iterator(); - while (iter.hasNext()){ - if (!oldReferences.contains(iter.next())){ + while (iter.hasNext()) { + if (!oldReferences.contains(iter.next())) { break checkIdentity; } } @@ -794,21 +999,23 @@ public class SetClasspathOperation extends JavaModelOperation { String[] requiredProjectNames = new String[newSize]; int index = 0; iter = newReferences.iterator(); - while (iter.hasNext()){ - requiredProjectNames[index++] = (String)iter.next(); + while (iter.hasNext()) { + requiredProjectNames[index++] = (String) iter.next(); } - Util.sort(requiredProjectNames); // ensure that if changed, the order is consistent - + Util.sort(requiredProjectNames); // ensure that if changed, the + // order is consistent + IProject[] requiredProjectArray = new IProject[newSize]; IWorkspaceRoot wksRoot = project.getWorkspace().getRoot(); - for (int i = 0; i < newSize; i++){ - requiredProjectArray[i] = wksRoot.getProject(requiredProjectNames[i]); + for (int i = 0; i < newSize; i++) { + requiredProjectArray[i] = wksRoot + .getProject(requiredProjectNames[i]); } - + description.setReferencedProjects(requiredProjectArray); project.setDescription(description, this.progressMonitor); - - } catch(CoreException e){ + + } catch (CoreException e) { throw new JavaModelException(e); } } @@ -822,32 +1029,32 @@ public class SetClasspathOperation extends JavaModelOperation { if (needValidation) { IJavaProject project = (IJavaProject) getElementToProcess(); - // retrieve classpath + // retrieve classpath IClasspathEntry[] entries = this.newRawPath; - if (entries == ReuseClasspath){ + if (entries == ReuseClasspath) { try { - entries = project.getRawClasspath(); + entries = project.getRawClasspath(); } catch (JavaModelException e) { return e.getJavaModelStatus(); } - } + } // retrieve output location IPath outputLocation = this.newOutputLocation; - if (outputLocation == ReuseOutputLocation){ + if (outputLocation == ReuseOutputLocation) { try { outputLocation = project.getOutputLocation(); } catch (JavaModelException e) { return e.getJavaModelStatus(); } } - + // perform validation -// return JavaConventions.validateClasspath( -// project, -// entries, -// outputLocation); + // return JavaConventions.validateClasspath( + // project, + // entries, + // outputLocation); } - + return JavaModelStatus.VERIFIED_OK; } }