/*
* Copyright (c) 2015 the original author or authors.
* 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:
* Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation
*/
package eclipsebuild.testing;
import java.io.File;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.gradle.api.file.EmptyFileVisitor;
import org.gradle.api.file.FileTree;
import org.gradle.api.file.FileVisitDetails;
import org.gradle.api.internal.tasks.testing.DefaultTestClassRunInfo;
import org.gradle.api.internal.tasks.testing.TestClassProcessor;
import org.gradle.api.internal.tasks.testing.TestClassRunInfo;
public final class EclipsePluginTestClassScanner implements Runnable {
private final FileTree candidateClassFiles;
private final TestClassProcessor testClassProcessor;
public EclipsePluginTestClassScanner(FileTree candidateClassFiles, TestClassProcessor testClassProcessor) {
this.candidateClassFiles = candidateClassFiles;
this.testClassProcessor = testClassProcessor;
}
@Override
public void run() {
this.candidateClassFiles.visit(new ClassFileVisitor() {
@Override
public void visitClassFile(FileVisitDetails fileDetails) {
String className = fileDetails.getRelativePath().getPathString().replaceAll("\\.class", "").replace('/', '.');
TestClassRunInfo testClass = new DefaultTestClassRunInfo(className);
EclipsePluginTestClassScanner.this.testClassProcessor.processTestClass(testClass);
}
});
}
private abstract class ClassFileVisitor extends EmptyFileVisitor {
@Override
public void visitFile(FileVisitDetails fileDetails) {
final File file = fileDetails.getFile();
if (isValidTestClassFile(file)) {
visitClassFile(fileDetails);
}
}
private boolean isValidTestClassFile(final File file) {
try {
return isTopLevelClass(file) && isConcreteClass(file);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private boolean isTopLevelClass(final File file) {
return file.getAbsolutePath().endsWith(".class") && !file.getAbsolutePath().contains("$");
}
private boolean isConcreteClass(File file) throws Exception {
ClassParser parser = new ClassParser(file.getAbsolutePath());
JavaClass javaClass = parser.parse();
return !javaClass.isAbstract() && !javaClass.isInterface();
}
public abstract void visitClassFile(FileVisitDetails fileDetails);
}
}