package org.eclipse.jdt.internal.core;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CompilationParticipant;
import org.eclipse.jdt.core.compiler.ReconcileContext;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
@SuppressWarnings({"rawtypes"})
public class ReconcileWorkingCopyOperation extends JavaModelOperation {
public static boolean PERF = false;
public int astLevel;
public boolean resolveBindings;
public HashMap problems;
public int reconcileFlags;
WorkingCopyOwner workingCopyOwner;
public org.eclipse.jdt.core.dom.CompilationUnit ast;
public JavaElementDeltaBuilder deltaBuilder;
public boolean requestorIsActive;
public ReconcileWorkingCopyOperation(IJavaElement workingCopy, int astLevel, int reconcileFlags, WorkingCopyOwner workingCopyOwner) {
super(new IJavaElement[] {workingCopy});
this.astLevel = astLevel;
this.reconcileFlags = reconcileFlags;
this.workingCopyOwner = workingCopyOwner;
}
@Override
protected void executeOperation() throws JavaModelException {
checkCanceled();
try {
beginTask(Messages.element_reconciling, 2);
CompilationUnit workingCopy = getWorkingCopy();
boolean wasConsistent = workingCopy.isConsistent();
IProblemRequestor problemRequestor = workingCopy.getPerWorkingCopyInfo();
if (problemRequestor != null)
problemRequestor = ((JavaModelManager.PerWorkingCopyInfo)problemRequestor).getProblemRequestor();
boolean defaultRequestorIsActive = problemRequestor != null && problemRequestor.isActive();
IProblemRequestor ownerProblemRequestor = this.workingCopyOwner.getProblemRequestor(workingCopy);
boolean ownerRequestorIsActive = ownerProblemRequestor != null && ownerProblemRequestor != problemRequestor && ownerProblemRequestor.isActive();
this.requestorIsActive = defaultRequestorIsActive || ownerRequestorIsActive;
this.deltaBuilder = new JavaElementDeltaBuilder(workingCopy);
makeConsistent(workingCopy);
if (!wasConsistent || ((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0)) {
notifyParticipants(workingCopy);
if (this.ast == null)
makeConsistent(workingCopy);
}
if (this.problems != null && (((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) || !wasConsistent)) {
if (defaultRequestorIsActive) {
reportProblems(workingCopy, problemRequestor);
}
if (ownerRequestorIsActive) {
reportProblems(workingCopy, ownerProblemRequestor);
}
}
JavaElementDelta delta = this.deltaBuilder.delta;
if (delta != null) {
addReconcileDelta(workingCopy, delta);
}
} finally {
done();
}
}
private void reportProblems(CompilationUnit workingCopy, IProblemRequestor problemRequestor) {
try {
problemRequestor.beginReporting();
for (Iterator iteraror = this.problems.values().iterator(); iteraror.hasNext();) {
CategorizedProblem[] categorizedProblems = (CategorizedProblem[]) iteraror.next();
if (categorizedProblems == null) continue;
for (int i = 0, length = categorizedProblems.length; i < length; i++) {
CategorizedProblem problem = categorizedProblems[i];
if (JavaModelManager.VERBOSE){
System.out.println("PROBLEM FOUND while reconciling : " + problem.getMessage());
}
if (this.progressMonitor != null && this.progressMonitor.isCanceled()) break;
problemRequestor.acceptProblem(problem);
}
}
} finally {
problemRequestor.endReporting();
}
}
protected CompilationUnit getWorkingCopy() {
return (CompilationUnit)getElementToProcess();
}
@Override
public boolean isReadOnly() {
return true;
}
public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(CompilationUnit workingCopy) throws JavaModelException {
if (!workingCopy.isConsistent()) {
if (this.problems == null) this.problems = new HashMap();
this.resolveBindings = this.requestorIsActive;
this.ast = workingCopy.makeConsistent(this.astLevel, this.resolveBindings, this.reconcileFlags, this.problems, this.progressMonitor);
this.deltaBuilder.buildDeltas();
if (this.ast != null && this.deltaBuilder.delta != null)
this.deltaBuilder.delta.changedAST(this.ast);
return this.ast;
}
if (this.ast != null)
return this.ast;
CompilationUnitDeclaration unit = null;
try {
JavaModelManager.getJavaModelManager().abortOnMissingSource.set(Boolean.TRUE);
CompilationUnit source = workingCopy.cloneCachingContents();
if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject())
&& (this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) {
this.resolveBindings = this.requestorIsActive;
if (this.problems == null)
this.problems = new HashMap();
unit =
CompilationUnitProblemFinder.process(
source,
this.workingCopyOwner,
this.problems,
this.astLevel != ICompilationUnit.NO_AST,
this.reconcileFlags,
this.progressMonitor);
if (this.progressMonitor != null) this.progressMonitor.worked(1);
}
if (this.astLevel != ICompilationUnit.NO_AST
&& unit !=null) {
Map options = workingCopy.getJavaProject().getOptions(true);
this.ast =
AST.convertCompilationUnit(
this.astLevel,
unit,
options,
this.resolveBindings,
source,
this.reconcileFlags,
this.progressMonitor);
if (this.ast != null) {
if (this.deltaBuilder.delta == null) {
this.deltaBuilder.delta = new JavaElementDelta(workingCopy);
}
this.deltaBuilder.delta.changedAST(this.ast);
}
if (this.progressMonitor != null) this.progressMonitor.worked(1);
}
} catch (JavaModelException e) {
if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject()))
throw e;
} finally {
JavaModelManager.getJavaModelManager().abortOnMissingSource.set(null);
if (unit != null) {
unit.cleanUp();
}
}
return this.ast;
}
private void notifyParticipants(final CompilationUnit workingCopy) {
IJavaProject javaProject = getWorkingCopy().getJavaProject();
CompilationParticipant[] participants = JavaModelManager.getJavaModelManager().compilationParticipants.getCompilationParticipants(javaProject);
if (participants == null) return;
final ReconcileContext context = new ReconcileContext(this, workingCopy);
for (int i = 0, length = participants.length; i < length; i++) {
final CompilationParticipant participant = participants[i];
SafeRunner.run(new ISafeRunnable() {
@Override
public void handleException(Throwable exception) {
if (exception instanceof Error) {
throw (Error) exception;
} else if (exception instanceof OperationCanceledException)
throw (OperationCanceledException) exception;
else if (exception instanceof UnsupportedOperationException) {
Util.log(exception, "Reconcile participant attempted to modify the buffer of the working copy being reconciled");
} else
Util.log(exception, "Exception occurred in reconcile participant");
}
@Override
public void run() throws Exception {
participant.reconcile(context);
}
});
}
}
@Override
protected IJavaModelStatus verify() {
IJavaModelStatus status = super.verify();
if (!status.isOK()) {
return status;
}
CompilationUnit workingCopy = getWorkingCopy();
if (!workingCopy.isWorkingCopy()) {
return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, workingCopy);
}
return status;
}
}