blob: f51ee63dfbffd44361fd44b9a84f7f2731a0d2d8 [file] [log] [blame]
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
package org.eclipse.jdt.internal.junit.ui;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchResultCollector;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.ISearchPattern;
import org.eclipse.jdt.core.search.SearchEngine;
/**
* Custom Search engine for suite() methods
*/
public class TestSearchEngine extends SearchEngine {
private class JUnitSearchResultCollector implements IJavaSearchResultCollector {
IProgressMonitor fProgressMonitor;
List fList;
public JUnitSearchResultCollector(List list, IProgressMonitor progressMonitor) {
fProgressMonitor= progressMonitor;
fList= list;
}
public void accept(IResource resource, int start, int end, IJavaElement enclosingElement, int accuracy) throws JavaModelException{
if (!(enclosingElement instanceof IMethod))
return;
IMethod method= (IMethod)enclosingElement;
if (!isTestType(method.getDeclaringType()) && !hasSuiteMethod(method.getDeclaringType()))
return;
if (!fList.contains(enclosingElement.getParent()))
fList.add(enclosingElement.getParent());
}
public IProgressMonitor getProgressMonitor() {
return fProgressMonitor;
}
public void aboutToStart() {
}
public void done() {
}
}
public List searchMethod(IRunnableContext context, final IJavaSearchScope scope)
throws InvocationTargetException {
final List typesFound= new ArrayList(200);
IRunnableWithProgress runnable= new IRunnableWithProgress() {
public void run(IProgressMonitor pm) {
try {
searchMethod(typesFound, scope, pm);
} catch (CoreException e) {;
Status status= new Status(IStatus.ERROR, JUnitPlugin.getPluginID(), IStatus.OK, "", e);
JUnitPlugin.getDefault().getLog().log(status);
MessageDialog.openError(JUnitPlugin.getActiveShell(), "JUnit Launcher Error", e.toString());
}
}
};
try {
context.run(true, true, runnable);
} catch (InterruptedException e) {
// do nothing user canceled the search process
}
return typesFound;
}
private List searchMethod(final List v, IJavaSearchScope scope, final IProgressMonitor progressMonitor) throws JavaModelException, CoreException {
IJavaSearchResultCollector collector= new JUnitSearchResultCollector(v, progressMonitor);
ISearchPattern suitePattern= createSearchPattern("suite() Test", IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, true); //$NON-NLS-1$
ISearchPattern testPattern= createSearchPattern("test*() void", IJavaSearchConstants.METHOD , IJavaSearchConstants.DECLARATIONS, true); //$NON-NLS-1$
search(ResourcesPlugin.getWorkspace(), createOrSearchPattern(suitePattern, testPattern), scope, collector);
return v;
}
public static List findTargets(IStructuredSelection selection) throws InvocationTargetException {
List v= new ArrayList(10);
Iterator elements= selection.iterator();
while(elements.hasNext()) {
Object o= elements.next();
collectTypes(v, o);
}
return v;
}
protected static void collectTypes(List v, Object scope) throws InvocationTargetException {
try {
scope= computeScope(scope);
while((scope instanceof IJavaElement) && !(scope instanceof ICompilationUnit) && (scope instanceof ISourceReference)) {
if(scope instanceof IType) {
if (hasSuiteMethod((IType)scope) || isTestType((IType)scope)) {
v.add(scope);
return;
}
}
scope= ((IJavaElement)scope).getParent();
}
if (scope instanceof ICompilationUnit) {
ICompilationUnit cu= (ICompilationUnit)scope;
IType[] types= cu.getAllTypes();
for (int i= 0; i < types.length; i++) {
if (hasSuiteMethod(types[i]) || isTestType(types[i]))
v.add(types[i]);
}
}
else if (scope instanceof IJavaElement) {
List found= searchSuiteMethods(new ProgressMonitorDialog(JUnitPlugin.getActiveShell()), (IJavaElement)scope);
v.addAll(found);
}
} catch (JavaModelException e) {
throw new InvocationTargetException(e);
}
}
protected static Object computeScope(Object scope) throws InvocationTargetException {
if (scope instanceof IProcess)
scope= ((IProcess)scope).getLaunch();
if (scope instanceof IDebugTarget)
scope= ((IDebugTarget)scope).getLaunch();
if (scope instanceof ILaunch)
scope= ((ILaunch)scope).getElement();
if (scope instanceof IFileEditorInput)
scope= ((IFileEditorInput)scope).getFile();
if (scope instanceof IResource)
scope= JavaCore.create((IResource)scope);
if (scope instanceof IClassFile) {
IClassFile cf= (IClassFile)scope;
try {
scope= cf.getType();
} catch (JavaModelException e) {
throw new InvocationTargetException(e);
}
}
return scope;
}
private static List searchSuiteMethods(IRunnableContext context, IJavaElement element)
throws InvocationTargetException {
IJavaSearchScope scope= TestSearchEngine.createJavaSearchScope(new IJavaElement[] { element });
return new TestSearchEngine().searchMethod(context, scope);
}
protected static boolean hasSuiteMethod(IType type){
try{
IMethod method= type.getMethod("suite", new String[0]);
if (method == null || !method.exists())
return false;
if (!Flags.isStatic(method.getFlags()) ||
!Flags.isPublic(method.getFlags()) ||
Flags.isAbstract(method.getDeclaringType().getFlags()) ||
!Flags.isPublic(method.getDeclaringType().getFlags()))
return false;
} catch (JavaModelException e){
String msg= "Warning: hasSuiteMethod(IType type) failed: " + type.getElementName();
Status status= new Status(IStatus.WARNING, JUnitPlugin.getPluginID(), IStatus.OK, msg, e);
JUnitPlugin.getDefault().getLog().log(status);
return false;
}
return true;
}
protected static boolean isTestType(IType type){
try{
if (Flags.isAbstract(type.getFlags()))
return false;
if (!Flags.isPublic(type.getFlags()))
return false;
IType[] interfaces= type.newTypeHierarchy(type.getJavaProject(), null).getAllSuperInterfaces(type);
for (int i=0; i < interfaces.length; i++)
if(interfaces[i].getFullyQualifiedName().equals("junit.framework.Test"))
return true;
} catch (JavaModelException e) {
String msg= "Warning: isTestType(IType type) failed: " + type.getElementName();
Status status= new Status(IStatus.WARNING, JUnitPlugin.getPluginID(), IStatus.OK, msg, e);
JUnitPlugin.getDefault().getLog().log(status);
}
return false;
}
}