package org.testng.eclipse.ui;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.ui.text.java.IInvocationContext;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jdt.ui.text.java.IProblemLocation;
import org.eclipse.jdt.ui.text.java.IQuickFixProcessor;
import org.testng.eclipse.TestNGPlugin;
import org.testng.eclipse.buildpath.BuildPathSupport;
public class TestNGQuickFixProcessor implements IQuickFixProcessor {
public IJavaCompletionProposal[] getCorrections(IInvocationContext context,
IProblemLocation[] locations) throws CoreException {
IJavaProject project = context.getCompilationUnit().getJavaProject();
if (!isJava5SyntaxSupported(project) || isTestNGContainerOnClasspath(project)) {
return null;
}
List<IJavaCompletionProposal> res = new ArrayList<>();
for (IProblemLocation problem : locations) {
int problemId = problem.getProblemId();
if (isImportProblem(problemId)) {
res = getAddTestNGToBuildPathProposals(context, problem, res);
}
}
if (res.isEmpty()) {
return null;
}
return (IJavaCompletionProposal[]) res.toArray(new IJavaCompletionProposal[res.size()]);
}
private boolean isImportProblem(int problemId) {
return (problemId == IProblem.UndefinedType) || (problemId == IProblem.ImportNotFound);
}
public boolean hasCorrections(ICompilationUnit unit, int problemId) {
return isImportProblem(problemId);
}
private boolean isJava5SyntaxSupported(IJavaProject project) {
String projectComplianceLevel = getSourceCompatabilityLevel(project);
return JavaCore.VERSION_1_5.compareTo(projectComplianceLevel) <= 0;
}
private boolean isTestNGContainerOnClasspath(IJavaProject project) {
try {
return BuildPathSupport.projectContainsClasspathEntry(project, BuildPathSupport.getTestNGClasspathEntry());
}
catch (JavaModelException e) {
return false;
}
}
private List<IJavaCompletionProposal> getAddTestNGToBuildPathProposals(IInvocationContext context,
IProblemLocation location,
List<IJavaCompletionProposal> proposals) {
try {
ICompilationUnit compilationUnit = context.getCompilationUnit();
String s = compilationUnit.getBuffer().getText(location.getOffset(), location.getLength());
if (maybeTestNGPackage(s)) {
proposals.add(new TestNGAddLibraryProposal(context, 11));
}
if (maybeTestNGAnnotation(s) && isAnnotation(context, location)) {
proposals.add(new TestNGAddLibraryProposal(context, 11, true));
}
}
catch (JavaModelException e) {
TestNGPlugin.log(e.getStatus());
}
return proposals;
}
private boolean maybeTestNGPackage(String s) {
return s.indexOf("org.testng") != -1; //$NON-NLS-1$
}
private boolean maybeTestNGAnnotation(String s) {
return "Test".equals(s) || "Configuration".equals(s)
|| "BeforeSuite".equals(s) || "AfterSuite".equals(s) || "BeforeTest".equals(s) || "AfterTest".equals(s)
|| "BeforeGroups".equals(s) || "AfterGroups".equals(s) || "BeforeClass".equals(s) || "AfterClass".equals(s)
|| "BeforeMethod".equals(s) || "AfterMethod".equals(s); //$NON-NLS-1$
}
public static String getSourceCompatabilityLevel(IJavaProject project) {
String complianceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
return complianceLevel;
}
private boolean isAnnotation(IInvocationContext context, IProblemLocation location) {
ASTNode node = location.getCoveredNode(context.getASTRoot());
return (node != null && node.getLocationInParent() == MarkerAnnotation.TYPE_NAME_PROPERTY);
}
}