Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2000, 2011 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.core;
 
 import java.net.URL;
 import java.util.Map;
 
 import  org.eclipse.core.resources.IFolder;
 import  org.eclipse.core.resources.IResource;
 import  org.eclipse.core.resources.IWorkspace;
 import  org.eclipse.core.resources.ResourcesPlugin;
 import  org.eclipse.core.runtime.CoreException;
 import  org.eclipse.core.runtime.IPath;
 
 public class ClasspathChange {
 	public static final int NO_DELTA = 0x00;
 	public static final int HAS_DELTA = 0x01;
 	public static final int HAS_PROJECT_CHANGE = 0x02;
 	public static final int HAS_LIBRARY_CHANGE = 0x04;
 
 
 	public ClasspathChange(JavaProject projectIClasspathEntry[] oldRawClasspath, IPath oldOutputLocationIClasspathEntry[] oldResolvedClasspath) {
 		this. = project;
 		this. = oldRawClasspath;
 		this. = oldOutputLocation;
 		this. = oldResolvedClasspath;
 	}
 
 	private void addClasspathDeltas(JavaElementDelta deltaIPackageFragmentRoot[] rootsint flag) {
 		for (int i = 0; i < roots.lengthi++) {
 			IPackageFragmentRoot root = roots[i];
 			delta.changed(rootflag);
 					|| (flag & .) != 0
 					|| (flag & .) != 0){
 				try {
 					root.close();
 				} catch (JavaModelException e) {
 					// ignore
 				}
 			}
 		}
 	}
 
 	/*
 	 * 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.
 	 */
 	private int classpathContains(IClasspathEntry[] listIClasspathEntry entry) {
 		IPath[] exclusionPatterns = entry.getExclusionPatterns();
 		IPath[] inclusionPatterns = entry.getInclusionPatterns();
 		int listLen = list == null ? 0 : list.length;
 		nextEntry: for (int i = 0; i < listLeni++) {
 			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 inclusion patterns
 					IPath[] otherIncludes = other.getInclusionPatterns();
 					if (inclusionPatterns != otherIncludes) {
 					    if (inclusionPatterns == nullcontinue;
						int includeLength = inclusionPatterns.length;
						if (otherIncludes == null || otherIncludes.length != includeLength)
							continue;
						for (int j = 0; j < includeLengthj++) {
							// compare toStrings instead of IPaths
							// since IPath.equals is specified to ignore trailing separators
							if (!inclusionPatterns[j].toString().equals(otherIncludes[j].toString()))
								continue nextEntry;
						}
					}
					// check exclusion patterns
					IPath[] otherExcludes = other.getExclusionPatterns();
					if (exclusionPatterns != otherExcludes) {
					    if (exclusionPatterns == nullcontinue;
						int excludeLength = exclusionPatterns.length;
						if (otherExcludes == null || otherExcludes.length != excludeLength)
							continue;
						for (int j = 0; j < excludeLengthj++) {
							// 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 -1;
	}
	/*
	 * Recursively adds all subfolders of <code>folder</code> to the given collection.
	 */
	private void collectAllSubfolders(IFolder folderArrayList collectionthrows JavaModelException {
		try {
			IResource[] membersfolder.members();
			for (int i = 0, max = members.length; i < maxi++) {
				IResource rmembers[i];
				if (r.getType() == IResource.FOLDER) {
					collection.add(r);
					collectAllSubfolders((IFolder)rcollection);
				}
			}
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.
	 */
	private ArrayList determineAffectedPackageFragments(IPath locationthrows JavaModelException {
		ArrayList fragments = new ArrayList();
		// 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
			for (int i = 0; i < classpath.lengthi++) {
				IClasspathEntry entry = classpath[i];
				IPath path = classpath[i].getPath();
				if (entry.getEntryKind() != . && path.isPrefixOf(location) && !path.equals(location)) {
					// now the output location becomes a package fragment - along with any subfolders
					ArrayList folders = new ArrayList();
					folders.add(folder);
					collectAllSubfolders(folderfolders);
					Iterator elements = folders.iterator();
					int segments = path.segmentCount();
					while (elements.hasNext()) {
						IFolder f = (IFolder) elements.next();
						IPath relativePath = f.getFullPath().removeFirstSegments(segments);
						String[] pkgName = relativePath.segments();
						IPackageFragment pkg = root.getPackageFragment(pkgName);
						if (!Util.isExcluded(pkg))
							fragments.add(pkg);
					}
				}
			}
		}
		return fragments;
	}
	public boolean equals(Object obj) {
		if (!(obj instanceof ClasspathChange))
			return false;
		return this..equals(((ClasspathChangeobj).);
	}
	/*
	 * Generates a classpath change delta for this classpath change.
	 * Returns whether a delta was generated, and whether project reference have changed.
	 */
	public int generateDelta(JavaElementDelta deltaboolean addClasspathChange) {
		JavaModelManager manager = JavaModelManager.getJavaModelManager();
		DeltaProcessingState state = manager.deltaState;
		if (state.findJavaProject(this..getElementName()) == null)
			// project doesn't exist yet (we're in an IWorkspaceRunnable)
			// no need to create a delta here and no need to index (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=133334)
			// the delta processor will create an ADDED project delta, and index the project
			return ;
		DeltaProcessor deltaProcessor = state.getDeltaProcessor();
		IClasspathEntry[] newResolvedClasspath = null;
		IPath newOutputLocation = null;
		int result = ;
		try {
			PerProjectInfo perProjectInfo = this..getPerProjectInfo();
			// get new info
			this..resolveClasspath(perProjectInfofalse/*don't use previous session values*/addClasspathChange);
			IClasspathEntry[] newRawClasspath;
			// use synchronized block to ensure consistency
			synchronized (perProjectInfo) {
				newRawClasspath = perProjectInfo.rawClasspath;
				newResolvedClasspath = perProjectInfo.getResolvedClasspath();
				newOutputLocation = perProjectInfo.outputLocation;
			}
			if (newResolvedClasspath == null) {
				// another thread reset the resolved classpath, use a temporary PerProjectInfo
				PerProjectInfo temporaryInfo = this..newTemporaryInfo();
				this..resolveClasspath(temporaryInfofalse/*don't use previous session values*/addClasspathChange);
				newRawClasspath = temporaryInfo.rawClasspath;
				newResolvedClasspath = temporaryInfo.getResolvedClasspath();
				newOutputLocation = temporaryInfo.outputLocation;
			}
			// check if raw classpath has changed
			if (this. != null && !JavaProject.areClasspathsEqual(this.newRawClasspaththis.newOutputLocation)) {
				result |= ;
				// reset containers that are no longer on the classpath
				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=139446)
				for (int i = 0, length = this..lengthi < lengthi++) {
					IClasspathEntry entry = this.[i];
						if (classpathContains(newRawClasspathentry) == -1)
							manager.containerPut(this.entry.getPath(), null);
					}
				}
			}
			// if no changes to resolved classpath, nothing more to do
			if (this. != null && JavaProject.areClasspathsEqual(this.newResolvedClasspaththis.newOutputLocation))
				return result;
			// close cached info
			this..close();
			// ensure caches of dependent projects are reset as well (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=207890)
			deltaProcessor.projectCachesToReset.add(this.);
catch (JavaModelException e) {
			}
			// project no longer exist
			return result;
		}
		if (this. == null)
			return result;
		result |= ;
		state.addForRefresh(this.); // ensure external jars are refreshed for this project (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=212769 )
		Map removedRoots = null;
		IPackageFragmentRoot[] roots = null;
		Map allOldRoots ;
		if ((allOldRoots = deltaProcessor.oldRoots) != null) {
	 		roots = (IPackageFragmentRoot[]) allOldRoots.get(this.);
		}
		if (roots != null) {
			removedRoots = new HashMap();
			for (int i = 0; i < roots.lengthi++) {
				IPackageFragmentRoot root = roots[i];
				removedRoots.put(root.getPath(), root);
			}
		}
		int newLength = newResolvedClasspath.length;
		int oldLength = this..length;
		for (int i = 0; i < oldLengthi++) {
			int index = classpathContains(newResolvedClasspaththis.[i]);
			if (index == -1) {
				// remote project changes
				int entryKind = this.[i].getEntryKind();
				if (entryKind == .) {
					result |= ;
					continue;
				}
				if (entryKind == .) {
					result |= ;
				}
				IPackageFragmentRoot[] pkgFragmentRoots = null;
				if (removedRoots != null) {
					PackageFragmentRoot oldRoot = (PackageFragmentRoot)  removedRoots.get(this.[i].getPath());
					if (oldRoot != null) { // use old root if any (could be none if entry wasn't bound)
						pkgFragmentRoots = new PackageFragmentRoot[] { oldRoot };
					}
				}
				if (pkgFragmentRoots == null) {
					try {
						ObjectVector accumulatedRoots = new ObjectVector();
						HashSet rootIDs = new HashSet(5);
						rootIDs.add(this..rootID());
							accumulatedRoots,
							rootIDs,
							null// inside original project
							false// don't retrieve exported roots
							null); /*no reverse map*/
						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=335986
						// When a package fragment's corresponding resource is removed from the project, 
						// IJavaProject#computePackageFragmentRoots() doesn't include that entry. Hence 
						// the cache become necessary in such cases. Add the cache to the accumulatedRoots 
						// only when it's not already present.
						RootInfo rootInfo = (RootInfostate.oldRoots.get(this.[i].getPath());
						if (rootInfo != null && rootInfo.cache != null) {
							IPackageFragmentRoot oldRoot = rootInfo.cache;
							boolean found = false;
							for (int j = 0; j < accumulatedRoots.size(); j++) {
								IPackageFragmentRoot root = (IPackageFragmentRootaccumulatedRoots.elementAt(j);
								if (root.getPath().equals(oldRoot.getPath())) {
									found = true;
									break;
								}
							}
							if (!found)
								accumulatedRoots.add(oldRoot);
						}
						pkgFragmentRoots = new PackageFragmentRoot[accumulatedRoots.size()];
						accumulatedRoots.copyInto(pkgFragmentRoots);
catch (JavaModelException e) {
						pkgFragmentRoots =  new PackageFragmentRoot[] {};
					}
				}
else {
				// remote project changes
					result |= ;
					continue;
				}
				if (index != i) { //reordering of the classpath
				}
				// check source attachment
				IPath newSourcePath = newResolvedClasspath[index].getSourceAttachmentPath();
				int sourceAttachmentFlags = getSourceAttachmentDeltaFlag(this.[i].getSourceAttachmentPath(), newSourcePath);
				IPath oldRootPath = this.[i].getSourceAttachmentRootPath();
				IPath newRootPath = newResolvedClasspath[index].getSourceAttachmentRootPath();
				int sourceAttachmentRootFlags = getSourceAttachmentDeltaFlag(oldRootPathnewRootPath);
				int flags = sourceAttachmentFlags | sourceAttachmentRootFlags;
				if (flags != 0) {
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)
						for (int j = 0; j < computedRoots.lengthj++) {
							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
							}
						}
					}
				}
			}
		}
		for (int i = 0; i < newLengthi++) {
			int index = classpathContains(this.newResolvedClasspath[i]);
			if (index == -1) {
				// remote project changes
				int entryKind = newResolvedClasspath[i].getEntryKind();
				if (entryKind == .) {
					result |= ;
					continue;
				}
				if (entryKind == .) {
					result |= ;
				}
// classpath reordering has already been generated in previous loop
		}
		// see if a change in output location will cause any package fragments to be added/removed
		if ((newOutputLocation == null && this. != null)
				|| (newOutputLocation != null && !newOutputLocation.equals(this.))) {
			try {
				Iterator iter = added.iterator();
				while (iter.hasNext()){
					delta.added(frag);
				}
				// see if this will cause any package fragments to be removed
				ArrayList removed = determineAffectedPackageFragments(newOutputLocation);
				iter = removed.iterator();
				while (iter.hasNext()) {
					delta.removed(frag);
				}
catch (JavaModelException e) {
			}
		}
		return result;
	}
	/*
	 * 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) {
else {
				return 0;
			}
else if (newPath == null) {
else if (!oldPath.equals(newPath)) {
else {
			return 0;
		}
	}
	public int hashCode() {
		return this..hashCode();
	}
	/*
	 * Request the indexing of entries that have been added, and remove the index for removed entries.
	 */
	public void requestIndexing() {
		IClasspathEntry[] newResolvedClasspath = null;
		try {
			newResolvedClasspath = this..getResolvedClasspath();
catch (JavaModelException e) {
			// project doesn't exist
			return;
		}
		JavaModelManager manager = JavaModelManager.getJavaModelManager();
		IndexManager indexManager = manager.indexManager;
		if (indexManager == null)
			return;
		DeltaProcessingState state = manager.deltaState;
		int newLength = newResolvedClasspath.length;
		int oldLength = this. == null ? 0 : this..length;
		for (int i = 0; i < oldLengthi++) {
			int index = classpathContains(newResolvedClasspaththis.[i]);
			if (index == -1) {
				// remote projects are not indexed in this project
					continue;
				}
				// 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.
				final IPath path = oldEntry.getPath();
				int changeKind = this.[i].getEntryKind();
				switch (changeKind) {
						char[][] inclusionPatterns = ((ClasspathEntry)oldEntry).fullInclusionPatternChars();
						char[][] exclusionPatterns = ((ClasspathEntry)oldEntry).fullExclusionPatternChars();
						indexManager.removeSourceFolderFromIndex(this.pathinclusionPatternsexclusionPatterns);
						break;
						if (state.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
						}
						break;
				}
			}
		}
		for (int i = 0; i < newLengthi++) {
			int index = classpathContains(this.newResolvedClasspath[i]);
			if (index == -1 || newResolvedClasspath[i].getEntryKind() == .) {
				// remote projects are not indexed in this project
				if (newResolvedClasspath[i].getEntryKind() == .){
					continue;
				}
				// Request indexing
				int entryKind = newResolvedClasspath[i].getEntryKind();
				URL newurl = ((ClasspathEntry)newResolvedClasspath[i]).getLibraryIndexLocation();
				switch (entryKind) {
						boolean pathHasChanged = true;
						IPath newPath = newResolvedClasspath[i].getPath();
						for (int j = 0; j < oldLengthj++) {
							if (oldEntry.getPath().equals(newPath)) {
								URL oldurl = ((ClasspathEntry)oldEntry).getLibraryIndexLocation();
								if (oldurl == null && newurl == null) {
									pathHasChanged = false;
else if (oldurl != null && newurl != null) {
									pathHasChanged = !(newurl.equals(oldurl));
else if (oldurl != null) {
									indexManager.removeIndex(newPath);
								}
								break;
							}
						}
						if (pathHasChanged) {
							indexManager.indexLibrary(newPaththis..getProject(), newurl);
						}
						break;
						IClasspathEntry entry = newResolvedClasspath[i];
						IPath path = entry.getPath();
						char[][] inclusionPatterns = ((ClasspathEntry)entry).fullInclusionPatternChars();
						char[][] exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
						indexManager.indexSourceFolder(this.pathinclusionPatternsexclusionPatterns);
						break;
				}
			}
		}
	}
	public String toString() {
		return "ClasspathChange: " + this..getElementName(); //$NON-NLS-1$
	}
New to GrepCode? Check out our FAQ X