package org.eclipse.jdt.internal.core.builder.impl;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;

import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.internal.core.builder.*;
import org.eclipse.jdt.internal.core.*;

import java.io.*;
import java.util.*;

/**
 * The Java Image Builder, which is a VA/Base builder.
 */
public class JavaBuilder extends IncrementalProjectBuilder {

	/**
	 * Flag indicating whether to persist built states between sessions.
	 */
	public static final boolean SAVE_ENABLED = true;	
/**
 * Constructs a new Java Builder.
 */
public JavaBuilder() {
}
	/**
	 * Run the Java Image Builder.
	 */
	protected IProject[] build(int kind, Map map, IProgressMonitor monitor) throws CoreException {

		if (!this.getProject().exists()) return new IProject[0];
		//if (!((JavaProject)getJavaProject()).hasSource()) return new IProject[0];
		
		JavaDevelopmentContextImpl dc = getDevelopmentContext();
		dc.setProgressMonitor(monitor);
		boolean ok = false;
		try {
			if (kind == FULL_BUILD) {
				fullBuild(dc, monitor);
			}
			else {
				Hashtable deltas = checkIncrementalBuild(monitor);
				if (deltas == null) {
					fullBuild(dc, monitor);
				}
				else {
					incrementalBuild(dc, deltas, monitor);
				}
			}
			ok = true;
		} catch (ImageBuilderInternalException e) {
			// Fix for 1FW2XY6: ITPJCORE:ALL - Image builder wrappers CoreException
			if (e.getThrowable() instanceof CoreException) {
				throw (CoreException) e.getThrowable();
			} else {
				throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("build.builderName"/*nonNLS*/), e));
			}
		} catch (OperationCanceledException e) {
			// Do nothing for now, and avoid propagating the exception.  
			// The finally block ensures we will do a full build next time.
			// See 1FVJ5Z8: ITPCORE:ALL - How should builders handle cancel?
		} finally {
			// Don't let DC hang onto progress monitor.
			dc.setProgressMonitor(null);
			if (!ok) {
				// If the build failed, clear out the previously built state,
				// forcing a full build next time.
				setLastBuiltState(null);
			}
			if (monitor != null) monitor.subTask(Util.bind("build.completed"/*nonNLS*/));
		}
		return getRequiredProjects(getLastBuiltState(monitor));
	}
	/**
	 * Checks whether we can do an incremental build.
	 * Returns a hashtable containing all the required deltas if yes, null if no.
	 *
	 * @return hashtable mapping from IProject to IResourceDelta for all required project deltas, or null
	 */
	protected Hashtable checkIncrementalBuild(IProgressMonitor monitor) throws CoreException {
		IState oldState = getLastBuiltState(monitor);
		if (oldState == null) {
			//System.out.println("No previous built state for: "+getProject().getName());			
			return null;
		}
		Hashtable deltas = new Hashtable(11);
		IProject project = getProject();

		if (monitor != null) monitor.subTask(Util.bind("build.readingDelta"/*nonNLS*/, project.getName()));
		IResourceDelta delta = getDelta(project);
		if (delta == null){
			//System.out.println("Missing delta for: "+ project.getName());			
			if (monitor != null) monitor.subTask(""/*nonNLS*/);
			return null;
		} else {
			deltas.put(project, delta);
		}
		IProject[] prereqs = getRequiredProjects(oldState);
		for (int i = 0; i < prereqs.length; ++i) {
			if (monitor != null)  monitor.subTask(Util.bind("build.readingDelta"/*nonNLS*/, prereqs[i].getName()));
			delta = getDelta(prereqs[i]);
			if (delta == null){
				//System.out.println("Missing delta for: "+ prereqs[i].getName());			
				if (monitor != null) monitor.subTask(""/*nonNLS*/);
				return null;
			} else {
				deltas.put(prereqs[i], delta);
			}
		}
		if (monitor != null) monitor.subTask(""/*nonNLS*/);
		return deltas;
	}
/**
 * Returns true if the class path has changed since the last built state.
 */
protected boolean classpathChanged(IState lastBuiltState) throws CoreException {
	try {
		IPackageFragmentRoot[] oldRoots = ((StateImpl) lastBuiltState).getPackageFragmentRootsInClassPath();
		IPackageFragmentRoot[] newRoots = ((JavaProject) getJavaProject()).getBuilderRoots(null);
		return !Util.equalArraysOrNull(oldRoots, newRoots);
	} catch (JavaModelException e) {
		throw new CoreException(
				new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, Util.bind("element.projectDoesNotExist"/*nonNLS*/, getProject().getFullPath().toString()), e));
	}
}
	/**
	 * Runs a full build.
	 */
	protected void fullBuild(JavaDevelopmentContextImpl dc, IProgressMonitor monitor) throws CoreException {
		IProject project = getProject();
		//System.out.println("FULL build of: "+project.getName());			

		/* create problem reporter and clear all problems */
		IProblemReporter problemReporter= new MarkerProblemReporter(project, dc);
		problemReporter.removeProblems(project);

		/* create and invoke the batch builder */
		// Pass the compiler options, needed for 1FVXS80: ITPJCORE:ALL - .class files are missing their LocalVariableTable
		ConfigurableOption[] options = JavaModelManager.convertConfigurableOptions(JavaCore.getOptions());
		setLastBuiltState(null); // free possible existing state
		IImageBuilder builder = dc.createState(project, null, problemReporter, options);
		setLastBuiltState(builder.getNewState());
	}
/**
 * Returns the development context to use for this builder.
 */
protected JavaDevelopmentContextImpl getDevelopmentContext() {
	return (JavaDevelopmentContextImpl) JavaModelManager.getJavaModelManager().getDevelopmentContext(getProject());
}
/**
 * Returns the Java view of the project.
 */
protected IJavaProject getJavaProject() {
	return JavaCore.create(getProject());
}
/**
 * Returns the last built state for this builder.
 */
protected IState getLastBuiltState(IProgressMonitor monitor) {
	return JavaModelManager.getJavaModelManager().getLastBuiltState(getProject(), monitor);
}
/**
 * Returns a problem factory for the given locale.
 */
public IProblemFactory getProblemFactory(Locale locale) {
	return ProblemFactory.getProblemFactory(locale);
}
	/**
	 * Returns the prerequisite projects for the given built state.
	 * Returns an empty array if state is null.
	 *
	 * @param the state or null
	 */
	protected IProject[] getRequiredProjects(IState state) {
		if (state == null) {
			return new IProject[0];
		}
		// This must not assume the given state is the current one.
		// It may be the old state.
		IProject project = getProject();
		IProject[] all = ((StateImpl) state).getClassPathProjects();
		Vector v = new Vector();
		for (int i = 0; i < all.length; ++i) {
			if (!all[i].equals(project)) {
				v.addElement(all[i]);
			}
		}
		IProject[] result = new IProject[v.size()];
		v.copyInto(result);
		return result;
	}
	/**
	 * Runs an incremental build.
	 *
	 * @param deltas maps from IProject to IResourceDelta for this builder's project and all prerequisite projects
	 */
	protected void incrementalBuild(JavaDevelopmentContextImpl dc, Hashtable deltas, IProgressMonitor monitor) throws CoreException {
		IProject project = getProject();
		//System.out.println("INCREMENTAL build of: "+project.getName());		
		StateImpl oldState = (StateImpl) getLastBuiltState(monitor);
		if (needIncrementalBuild(oldState, deltas)) {
			IncrementalImageBuilder builder = new IncrementalImageBuilder(oldState, project, null);
			builder.applySourceDelta(deltas);
			setLastBuiltState(builder.getNewState());
		}
		else {
			/* Still update resources in binary output */
			BuildNotifier notifier = new BuildNotifier((JavaDevelopmentContextImpl) dc, false);
			notifier.begin();
			try {
				ProjectResourceCopier copier = new ProjectResourceCopier(getJavaProject(), dc, notifier, 1.0f);
				IResourceDelta change = (IResourceDelta) deltas.get(project);
				copier.updateAffectedResources(change);
			} finally {
				notifier.done();
			}
		}
	}
/**
 * Checks whether this is an empty delta as far as the builder is concerned.
 */
protected boolean isEmpty(IResourceDelta change) {
	// Made checks more selective for 1FW1S0Y: ITPJCORE:ALL - Java builder builds when non-Java files affected
	if (change == null)
		return true;
	int kind = change.getKind();
	boolean isAdded = kind == IResourceDelta.ADDED;
	boolean isRemoved = kind == IResourceDelta.REMOVED;
	boolean isChanged = kind == IResourceDelta.CHANGED;
	int flags = change.getFlags();
	boolean contentChanged = isChanged && (flags & IResourceDelta.CONTENT) != 0;
	String extension = change.getFullPath().getFileExtension();
	boolean isJavaOrClassFile = extension != null && (extension.equalsIgnoreCase("java"/*nonNLS*/) || extension.equalsIgnoreCase("class"/*nonNLS*/));
	boolean isArchive = extension != null && (extension.equalsIgnoreCase("zip"/*nonNLS*/) || extension.equalsIgnoreCase("jar"/*nonNLS*/));
	
	// care about added, removed and modified (content actually modified) .java and .class files
	if (isJavaOrClassFile && (isAdded || isRemoved || contentChanged))
		return false;
	// care about added, removed and modified (content actually modified) .jar and .zip files
	if (isArchive && (isAdded || isRemoved || contentChanged))
		return false;
		
	// care about all folder additions and removals since they may represent package fragments
	IResource resource = change.getResource();
	if (resource != null){
		int type = resource.getType();
		// may have been a container previously if its type is changing
		boolean isFolder = (flags & IResourceDelta.TYPE) != 0 || type == IResource.FOLDER;
		if (isFolder && (isAdded || isRemoved))
			return false;
	}
	// recurse on children
	IResourceDelta[] children = change.getAffectedChildren();
	for (int i = 0; i < children.length; ++i) {
		if (!isEmpty(children[i]))
			return false;
	}
	return true;
}
	/**
	 * Checks whether an incremental build is really necessary.
	 */
	protected boolean needIncrementalBuild(StateImpl oldState, Hashtable deltas) throws CoreException {
		if (classpathChanged(oldState)) {
			return true;
		}
		for (Enumeration e = deltas.elements(); e.hasMoreElements();) {
			IResourceDelta delta = (IResourceDelta) e.nextElement();
			if (!isEmpty(delta)) {
				return true;
			}
		}
		return false;
	}
/**
 * Returns true if the output location has changed since the last built state.
 */
protected boolean outputLocationChanged(IState lastBuiltState) throws CoreException {
	try {
		IPath oldOutputLocation = ((StateImpl) lastBuiltState).getOutputLocation();
		IPath newOutputLocation = getJavaProject().getOutputLocation();
		return !oldOutputLocation.equals(newOutputLocation);
	} catch (JavaModelException e) {
		throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, Util.bind("element.projectDoesNotExist"/*nonNLS*/, getProject().getFullPath().toString()), e));
	}
}
protected void setLastBuiltState(IState state) {
	JavaModelManager.getJavaModelManager().setLastBuiltState(getProject(), state);
}
/**
 * String representation for debugging purposes
 */
public String toString() {
	IState lastBuiltState = getLastBuiltState(null);
	if (lastBuiltState == null) {
		return "JavaBuilder(no built state)"/*nonNLS*/;
	} else {
		return "JavaBuilder("/*nonNLS*/ + lastBuiltState + ")"/*nonNLS*/;
	}
}
}
