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.builder;
 
 import  org.eclipse.core.resources.*;
 import  org.eclipse.core.runtime.*;
 
 
 import java.io.*;
 import java.util.*;
 
 public class JavaBuilder extends IncrementalProjectBuilder {
 
 IProject currentProject;
 IWorkspaceRoot workspaceRoot;
 SimpleLookupTable binaryLocationsPerProject// maps a project to its binary resources (output folders, class folders, zip/jar files)
 public State lastState;
 public static final String SOURCE_ID = "JDT"//$NON-NLS-1$
 
 public static boolean DEBUG = false;
 public static boolean SHOW_STATS = false;

A list of project names that have been built. This list is used to reset the JavaModel.existingExternalFiles cache when a build cycle begins so that deleted external jars are discovered.
 
 static ArrayList builtProjects = null;
 
 public static IMarker[] getProblemsFor(IResource resource) {
 	try {
 		if (resource != null && resource.exists()) {
 			IMarker[] markers = resource.findMarkers(.false, IResource.DEPTH_INFINITE);
 			Set markerTypes = JavaModelManager.getJavaModelManager()..managedMarkerTypes();
 			if (markerTypes.isEmpty()) return markers;
 			ArrayList markerList = new ArrayList(5);
 			for (int i = 0, length = markers.length; i < lengthi++) {
 				markerList.add(markers[i]);
 			}
 			Iterator iterator = markerTypes.iterator();
 			while (iterator.hasNext()) {
 				markers = resource.findMarkers((Stringiterator.next(), false, IResource.DEPTH_INFINITE);
 				for (int i = 0, length = markers.length; i < lengthi++) {
 					markerList.add(markers[i]);
 				}
 			}
 			IMarker[] result;
 			markerList.toArray(result = new IMarker[markerList.size()]);
 			return result;
 		}
 	} catch (CoreException e) {
 		// assume there are no problems
 	}
 	return new IMarker[0];
 }
 
 public static IMarker[] getTasksFor(IResource resource) {
 	try {
 		if (resource != null && resource.exists())
 			return resource.findMarkers(.false, IResource.DEPTH_INFINITE);
 	} catch (CoreException e) {
 		// assume there are no tasks
 	}
 	return new IMarker[0];
 }

Hook allowing to initialize some static state before a complete build iteration. This hook is invoked during PRE_AUTO_BUILD notification
 
 public static void buildStarting() {
 	// build is about to start
 }

Hook allowing to reset some static state after a complete build iteration. This hook is invoked during POST_AUTO_BUILD notification
 
 public static void buildFinished() {
	BuildNotifier.resetProblemCounters();
public static void removeProblemsFor(IResource resource) {
	try {
		if (resource != null && resource.exists()) {
			resource.deleteMarkers(.false, IResource.DEPTH_INFINITE);
			// delete managed markers
			if (markerTypes.size() == 0) return;
			Iterator iterator = markerTypes.iterator();
			while (iterator.hasNext())
				resource.deleteMarkers((Stringiterator.next(), false, IResource.DEPTH_INFINITE);
		}
catch (CoreException e) {
		// assume there were no problems
	}
public static void removeTasksFor(IResource resource) {
	try {
		if (resource != null && resource.exists())
			resource.deleteMarkers(.false, IResource.DEPTH_INFINITE);
catch (CoreException e) {
		// assume there were no problems
	}
public static void removeProblemsAndTasksFor(IResource resource) {
	try {
		if (resource != null && resource.exists()) {
			resource.deleteMarkers(.false, IResource.DEPTH_INFINITE);
			resource.deleteMarkers(.false, IResource.DEPTH_INFINITE);
			// delete managed markers
			if (markerTypes.size() == 0) return;
			Iterator iterator = markerTypes.iterator();
			while (iterator.hasNext())
				resource.deleteMarkers((Stringiterator.next(), false, IResource.DEPTH_INFINITE);
		}
catch (CoreException e) {
		// assume there were no problems
	}
public static State readState(IProject projectDataInputStream inthrows IOException {
	return State.read(projectin);
public static void writeState(Object stateDataOutputStream outthrows IOException {
	((Statestate).write(out);
protected IProject[] build(int kindMap ignored, IProgressMonitor monitorthrows CoreException {
	if (this. == null || !this..isAccessible()) return new IProject[0];
	if ()
		..println("\nStarting build of " + this..getName() //$NON-NLS-1$
" @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
	this. = new BuildNotifier(monitorthis.);
	boolean ok = false;
	try {
		kind = initializeBuilder(kindtrue);
		if (isWorthBuilding()) {
			if (kind == FULL_BUILD) {
				if ()
					..println("Performing full build as requested by user"); //$NON-NLS-1$
else {
				if ((this. = getLastState(this.)) == null) {
					if ()
						..println("Performing full build since last saved state was not found"); //$NON-NLS-1$
else if (hasClasspathChanged()) {
					// if the output location changes, do not delete the binary files from old location
					// the user may be trying something
					if ()
						..println("Performing full build since classpath has changed"); //$NON-NLS-1$
else if (this...length > 0) {
					// if there is no source to compile & no classpath changes then we are done
					if (deltas == null) {
						if ()
							..println("Performing full build since deltas are missing after incremental request"); //$NON-NLS-1$
else if (deltas.elementSize > 0) {
						buildDeltas(deltas);
else if () {
						..println("Nothing to build since deltas were empty"); //$NON-NLS-1$
					}
else {
					if (hasStructuralDelta()) { // double check that a jar file didn't get replaced in a binary project
						if ()
							..println("Performing full build since there are structural deltas"); //$NON-NLS-1$
else {
						if ()
							..println("Nothing to build since there are no source folders and no deltas"); //$NON-NLS-1$
					}
				}
			}
			ok = true;
		}
catch (CoreException e) {
		Util.log(e"JavaBuilder handling CoreException while building: " + this..getName()); //$NON-NLS-1$
		Util.log(e.getThrowable(), "JavaBuilder handling ImageBuilderInternalException while building: " + this..getName()); //$NON-NLS-1$
		// do not log this exception since its thrown to handle aborted compiles because of missing source files
		if ()
			..println(Messages.bind(.e.missingSourceFile));
		removeProblemsAndTasksFor(this.); // make this the only problem for this project
		IMarker marker = this..createMarker(.);
		marker.setAttributes(
			new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IMarker.SOURCE_ID},
			new Object[] {
				Messages.bind(.e.missingSourceFile),
				new Integer(IMarker.SEVERITY_ERROR),
			}
		);
finally {
		for (int i = 0, l = this. == null ? 0 : this..lengthi < li++)
		if (!ok)
			// If the build failed, clear the previously built state, forcing a full build next time.
		this..done();
	}
	IProject[] requiredProjects = getRequiredProjects(true);
	if ()
		..println("Finished build of " + this..getName() //$NON-NLS-1$
" @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
	return requiredProjects;
private void buildAll() {
	if ( && this. != null)
		..println("Clearing last state : " + this.); //$NON-NLS-1$
	BatchImageBuilder imageBuilder = new BatchImageBuilder(thistrue);
	imageBuilder.build();
	recordNewState(imageBuilder.newState);
private void buildDeltas(SimpleLookupTable deltas) {
	if ( && this. != null)
		..println("Clearing last state : " + this.); //$NON-NLS-1$
	clearLastState(); // clear the previously built state so if the build fails, a full build will occur next time
	if (imageBuilder.build(deltas)) {
		recordNewState(imageBuilder.newState);
else {
		if ()
			..println("Performing full build since incremental build failed"); //$NON-NLS-1$
	}
protected void clean(IProgressMonitor monitorthrows CoreException {
	if (this. == null || !this..isAccessible()) return;
	if ()
		..println("\nCleaning " + this..getName() //$NON-NLS-1$
" @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
	this. = new BuildNotifier(monitorthis.);
	try {
		initializeBuilder(CLEAN_BUILD, true);
		if ()
			..println("Clearing last state as part of clean : " + this.); //$NON-NLS-1$
		new BatchImageBuilder(thisfalse).cleanOutputFolders(false);
catch (CoreException e) {
		Util.log(e"JavaBuilder handling CoreException while cleaning: " + this..getName()); //$NON-NLS-1$
finally {
		this..done();
	}
	if ()
		..println("Finished cleaning " + this..getName() //$NON-NLS-1$
" @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
private void createInconsistentBuildMarker(CoreException coreExceptionthrows CoreException {
	String message = null;
	IStatus status = coreException.getStatus();
 	if (status.isMultiStatus()) {
 		IStatus[] children = status.getChildren();
 		if (children != null && children.length > 0)
 		    message = children[0].getMessage();
 	}
 	if (message == null)
 		message = coreException.getMessage();
	IMarker marker = this..createMarker(.);
	marker.setAttributes(
		new String[] {IMarker.MESSAGE, IMarker.SEVERITY, ., IMarker.SOURCE_ID},
		new Object[] {
			new Integer(IMarker.SEVERITY_ERROR),
		}
	);
private void cleanup() {
	this. = null;
	this. = null;
	this. = null;
	this. = null;
private void clearLastState() {
	JavaModelManager.getJavaModelManager().setLastBuiltState(this.null);
boolean filterExtraResource(IResource resource) {
	if (this. != null) {
		char[] name = resource.getName().toCharArray();
		for (int i = 0, l = this..lengthi < li++)
			if (CharOperation.match(this.[i], nametrue))
				return true;
	}
	if (this. != null) {
		IPath path = resource.getProjectRelativePath();
		String pathName = path.toString();
		int count = path.segmentCount();
		if (resource.getType() == IResource.FILE) count--;
		for (int i = 0, l = this..lengthi < li++)
			if (pathName.indexOf(this.[i]) != -1)
				for (int j = 0; j < countj++)
					if (this.[i].equals(path.segment(j)))
						return true;
	}
	return false;
	IResourceDelta delta = getDelta(this.);
	if (delta != null) {
		if (delta.getKind() != IResourceDelta.NO_CHANGE) {
			if ()
				..println("Found source delta for: " + this..getName()); //$NON-NLS-1$
			deltas.put(this.delta);
		}
else {
		if ()
			..println("Missing delta for: " + this..getName()); //$NON-NLS-1$
		this..subTask(""); //$NON-NLS-1$
		return null;
	}
	nextProject : for (int i = 0, l = keyTable.lengthi < li++) {
		IProject p = (IProject) keyTable[i];
		if (p != null && p != this.) {
			if (!this..wasStructurallyChanged(ps)) { // see if we can skip its delta
				if (s.wasNoopBuild())
					continue nextProject; // project has no source folders and can be skipped
				ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) valueTable[i];
				boolean canSkip = true;
				for (int j = 0, m = classFoldersAndJars.lengthj < mj++) {
					if (classFoldersAndJars[j].isOutputFolder())
						classFoldersAndJars[j] = null// can ignore output folder since project was not structurally changed
					else
						canSkip = false;
				}
				if (canSkipcontinue nextProject; // project has no structural changes in its output folders
			}
			this..subTask(Messages.bind(.p.getName()));
			delta = getDelta(p);
			if (delta != null) {
				if (delta.getKind() != IResourceDelta.NO_CHANGE) {
					if ()
						..println("Found binary delta for: " + p.getName()); //$NON-NLS-1$
					deltas.put(pdelta);
				}
else {
				if ()
					..println("Missing delta for: " + p.getName());	 //$NON-NLS-1$
				this..subTask(""); //$NON-NLS-1$
				return null;
			}
		}
	}
	this..subTask(""); //$NON-NLS-1$
	return deltas;
public State getLastState(IProject project) {
	return (State) JavaModelManager.getJavaModelManager().getLastBuiltState(projectthis..);
/* Return the list of projects for which it requires a resource delta. This builder's project
* is implicitly included and need not be specified. Builders must re-specify the list
* of interesting projects every time they are run as this is not carried forward
* beyond the next build. Missing projects should be specified but will be ignored until
* they are added to the workspace.
*/
private IProject[] getRequiredProjects(boolean includeBinaryPrerequisites) {
	if (this. == null || this. == nullreturn new IProject[0];
	ArrayList projects = new ArrayList();
	ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
	try {
		for (int i = 0, l = entries.lengthi < li++) {
			IClasspathEntry entry = entries[i];
			IPath path = entry.getPath();
			IProject p = null;
			switch (entry.getEntryKind()) {
					p = this..getProject(path.lastSegment()); // missing projects are considered too
					if (((ClasspathEntryentry).isOptional() && !JavaProject.hasJavaNature(p)) // except if entry is optional
						p = null;
					break;
					if (includeBinaryPrerequisites && path.segmentCount() > 0) {
						// some binary resources on the class path can come from projects that are not included in the project references
						IResource resource = this..findMember(path.segment(0));
						if (resource instanceof IProject) {
							p = (IProject) resource;
else {
							resource = externalFoldersManager.getFolder(path);
							if (resource != null)
								p = resource.getProject();
						}
					}
			}
			if (p != null && !projects.contains(p))
				projects.add(p);
		}
catch(JavaModelException e) {
		return new IProject[0];
	}
	IProject[] result = new IProject[projects.size()];
	projects.toArray(result);
	return result;
boolean hasBuildpathErrors() throws CoreException {
	IMarker[] markers = this..findMarkers(.false, IResource.DEPTH_ZERO);
	for (int i = 0, l = markers.length; i < li++)
		if (markers[i].getAttribute(., -1) == .)
			return true;
	return false;
private boolean hasClasspathChanged() {
	ClasspathMultiDirectory[] oldSourceLocations = this..;
	int newLength = newSourceLocations.length;
	int oldLength = oldSourceLocations.length;
	int no;
	for (n = o = 0; n < newLength && o < oldLengthn++, o++) {
		if (newSourceLocations[n].equals(oldSourceLocations[o])) continue// checks source & output folders
		try {
			if (newSourceLocations[n]..members().length == 0) { // added new empty source folder
				o--;
				continue;
else if (this..isSourceFolderEmpty(oldSourceLocations[o].)) {
				n--;
				continue;
			}
catch (CoreException ignore) { // skip it
		}
		if () {
			..println("New location: " + newSourceLocations[n] + "\n!= old location: " + oldSourceLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
			printLocations(newSourceLocationsoldSourceLocations);
		}
		return true;
	}
	while (n < newLength) {
		try {
			if (newSourceLocations[n]..members().length == 0) { // added new empty source folder
				n++;
				continue;
			}
catch (CoreException ignore) { // skip it
		}
		if () {
			..println("Added non-empty source folder"); //$NON-NLS-1$
			printLocations(newSourceLocationsoldSourceLocations);
		}
		return true;
	}
	while (o < oldLength) {
		if (this..isSourceFolderEmpty(oldSourceLocations[o].)) {
			o++;
			continue;
		}
		if () {
			..println("Removed non-empty source folder"); //$NON-NLS-1$
			printLocations(newSourceLocationsoldSourceLocations);
		}
		return true;
	}
	ClasspathLocation[] newBinaryLocations = this..;
	ClasspathLocation[] oldBinaryLocations = this..;
	newLength = newBinaryLocations.length;
	oldLength = oldBinaryLocations.length;
	for (n = o = 0; n < newLength && o < oldLengthn++, o++) {
		if (newBinaryLocations[n].equals(oldBinaryLocations[o])) continue;
		if () {
			..println("New location: " + newBinaryLocations[n] + "\n!= old location: " + oldBinaryLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
			printLocations(newBinaryLocationsoldBinaryLocations);
		}
		return true;
	}
	if (n < newLength || o < oldLength) {
		if () {
			..println("Number of binary folders/jar files has changed:"); //$NON-NLS-1$
			printLocations(newBinaryLocationsoldBinaryLocations);
		}
		return true;
	}
	return false;
private boolean hasJavaBuilder(IProject projectthrows CoreException {
	ICommand[] buildCommands = project.getDescription().getBuildSpec();
	for (int i = 0, l = buildCommands.length; i < li++)
		if (buildCommands[i].getBuilderName().equals(.))
			return true;
	return false;
private boolean hasStructuralDelta() {
	// handle case when currentProject has only .class file folders and/or jar files... no source/output folders
	IResourceDelta delta = getDelta(this.);
	if (delta != null && delta.getKind() != IResourceDelta.NO_CHANGE) {
		if (classFoldersAndJars != null) {
			for (int i = 0, l = classFoldersAndJars.lengthi < li++) {
				ClasspathLocation classFolderOrJar = classFoldersAndJars[i]; // either a .class file folder or a zip/jar file
				if (classFolderOrJar != null) {
					IPath p = classFolderOrJar.getProjectRelativePath();
					if (p != null) {
						IResourceDelta binaryDelta = delta.findMember(p);
						if (binaryDelta != null && binaryDelta.getKind() != IResourceDelta.NO_CHANGE)
							return true;
					}
				}
			}
		}
	}
	return false;
private int initializeBuilder(int kindboolean forBuildthrows CoreException {
	// some calls just need the nameEnvironment initialized so skip the rest
	this. = (JavaProject) JavaCore.create(this.);
	this. = this..getWorkspace().getRoot();
	if (forBuild) {
		// cache the known participants for this project
		if (this. != null)
			for (int i = 0, l = this..lengthi < li++)
					kind = FULL_BUILD;
		// Flush the existing external files cache if this is the beginning of a build cycle
		String projectName = this..getName();
		if ( == null || .contains(projectName)) {
		}
		.add(projectName);
	}
	if (forBuild) {
		char[][] filters = filterSequence != null && filterSequence.length() > 0
			? CharOperation.splitAndTrimOn(','filterSequence.toCharArray())
null;
		if (filters == null) {
else {
			int fileCount = 0, folderCount = 0;
			for (int i = 0, l = filters.lengthi < li++) {
				char[] f = filters[i];
				if (f.length == 0) continue;
				if (f[f.length - 1] == '/'folderCount++; else fileCount++;
			}
			this. = new char[fileCount][];
			this. = new String[folderCount];
			for (int i = 0, l = filters.lengthi < li++) {
				char[] f = filters[i];
				if (f.length == 0) continue;
				if (f[f.length - 1] == '/')
					this.[--folderCount] = new String(f, 0, f.length - 1);
				else
					this.[--fileCount] = f;
			}
		}
	}
	return kind;
private boolean isClasspathBroken(IClasspathEntry[] classpath, IProject pthrows CoreException {
	IMarker[] markers = p.findMarkers(.false, IResource.DEPTH_ZERO);
	for (int i = 0, l = markers.length; i < li++)
		if (markers[i].getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR)
			return true;
	return false;
private boolean isWorthBuilding() throws CoreException {
	boolean abortBuilds =
	if (!abortBuildsreturn true;
	// Abort build only if there are classpath errors
		if ()
			..println("Aborted build because project has classpath errors (incomplete or involved in cycle)"); //$NON-NLS-1$
		removeProblemsAndTasksFor(this.); // remove all compilation problems
		IMarker marker = this..createMarker(.);
		marker.setAttributes(
			new String[] {IMarker.MESSAGE, IMarker.SEVERITY, ., IMarker.SOURCE_ID},
			new Object[] {
				new Integer(IMarker.SEVERITY_ERROR),
			}
		);
		return false;
	}
		return true;
	// make sure all prereq projects have valid build states... only when aborting builds since projects in cycles do not have build states
	// except for projects involved in a 'warning' cycle (see below)
	IProject[] requiredProjects = getRequiredProjects(false);
	for (int i = 0, l = requiredProjects.length; i < li++) {
		IProject p = requiredProjects[i];
		if (getLastState(p) == null)  {
			// The prereq project has no build state: if this prereq project has a 'warning' cycle marker then allow build (see bug id 23357)
			JavaProject prereq = (JavaProject) JavaCore.create(p);
				if ()
					..println("Continued to build even though prereq project " + p.getName() //$NON-NLS-1$
" was not built since its part of a cycle"); //$NON-NLS-1$
				continue;
			}
			if (!hasJavaBuilder(p)) {
				if ()
					..println("Continued to build even though prereq project " + p.getName() //$NON-NLS-1$
" is not built by JavaBuilder"); //$NON-NLS-1$
				continue;
			}
			if ()
				..println("Aborted build because prereq project " + p.getName() //$NON-NLS-1$
" was not built"); //$NON-NLS-1$
			removeProblemsAndTasksFor(this.); // make this the only problem for this project
			IMarker marker = this..createMarker(.);
			marker.setAttributes(
				new String[] {IMarker.MESSAGE, IMarker.SEVERITY, ., IMarker.SOURCE_ID},
				new Object[] {
					new Integer(IMarker.SEVERITY_ERROR),
				}
			);
			return false;
		}
	}
	return true;
/*
 * Instruct the build manager that this project is involved in a cycle and
 * needs to propagate structural changes to the other projects in the cycle.
 */
	LinkedHashSet cycleParticipants = new LinkedHashSet(3);
	this..updateCycleParticipants(new ArrayList(), cycleParticipantsthis.new HashSet(3), null);
	IPath currentPath = this..getPath();
	Iterator icycleParticipants.iterator();
	while (i.hasNext()) {
		IPath participantPath = (IPath) i.next();
		if (participantPath != currentPath) {
			IProject project = this..getProject(participantPath.segment(0));
			if (hasBeenBuilt(project)) {
				if ()
					..println("Requesting another build iteration since cycle participant " + project.getName() //$NON-NLS-1$
" has not yet seen some structural changes"); //$NON-NLS-1$
				return;
			}
		}
	}
private void printLocations(ClasspathLocation[] newLocationsClasspathLocation[] oldLocations) {
	..println("New locations:"); //$NON-NLS-1$
	for (int i = 0, length = newLocations.lengthi < lengthi++)
		..println("    " + newLocations[i].debugPathString()); //$NON-NLS-1$
	..println("Old locations:"); //$NON-NLS-1$
	for (int i = 0, length = oldLocations.lengthi < lengthi++)
		..println("    " + oldLocations[i].debugPathString()); //$NON-NLS-1$
private void recordNewState(State state) {
	for (int i = 0, l = keyTable.lengthi < li++) {
		IProject prereqProject = (IProject) keyTable[i];
		if (prereqProject != null && prereqProject != this.)
			state.recordStructuralDependency(prereqProjectgetLastState(prereqProject));
	}
	if ()
		..println("Recording new state : " + state); //$NON-NLS-1$
	// state.dump();
	JavaModelManager.getJavaModelManager().setLastBuiltState(this.state);
String representation for debugging purposes
public String toString() {
	return this. == null
"JavaBuilder for unknown project" //$NON-NLS-1$
"JavaBuilder for " + this..getName(); //$NON-NLS-1$
New to GrepCode? Check out our FAQ X