package org.netbeans.gradle.project.java.test; import java.awt.event.ActionEvent; import java.io.File; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.SwingUtilities; import org.jtrim.cancel.Cancellation; import org.jtrim.cancel.CancellationToken; import org.jtrim.concurrent.CancelableTask; import org.jtrim.utils.ExceptionHelper; import org.netbeans.api.project.Project; import org.netbeans.gradle.model.java.JavaSourceGroup; import org.netbeans.gradle.model.java.JavaSourceSet; import org.netbeans.gradle.project.NbStrings; import org.netbeans.gradle.project.java.JavaExtension; import org.netbeans.gradle.project.output.OpenEditorOutputListener; import org.netbeans.gradle.project.util.NbTaskExecutors; import org.netbeans.gradle.project.util.StringUtils; import org.netbeans.gradle.project.view.GradleActionProvider; import org.netbeans.modules.gsf.testrunner.ui.api.TestsuiteNode; import org.netbeans.spi.project.ActionProvider; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; public final class JavaTestsuiteNode extends TestsuiteNode { private static final String[] EXTENSIONS = {".java", ".groovy", ".scala"}; private final JavaExtension javaExt; private final TestTaskName testTaskName; public JavaTestsuiteNode( String suiteName, boolean filtered, JavaExtension javaExt, TestTaskName testTaskName) { super(suiteName, filtered); ExceptionHelper.checkNotNullArgument(javaExt, "javaExt"); ExceptionHelper.checkNotNullArgument(testTaskName, "testTaskName"); this.javaExt = javaExt; this.testTaskName = testTaskName; } @Override public Action[] getActions(boolean context) { return new Action[] { getJumpToSourcesAction(), getRerunTestAction(), }; } @Override public Action getPreferredAction() { return getJumpToSourcesAction(); } private String getTestClassName() { return StringUtils.getTopMostClassName(suiteName); } private static FileObject tryGetTestFile(File root, String relPath) { FileObject rootObj = FileUtil.toFileObject(root); if (rootObj == null) { return null; } for (String extension: EXTENSIONS) { FileObject sourceFile = rootObj.getFileObject(relPath + extension); if (sourceFile != null) { return sourceFile; } } return null; } private static FileObject tryGetTestFile(JavaSourceGroup sourceGroup, String relPath) { for (File root: sourceGroup.getSourceRoots()) { FileObject result = tryGetTestFile(root, relPath); if (result != null) { return result; } } return null; } private static FileObject tryGetTestFile(JavaSourceSet sourceSet, String relPath) { for (JavaSourceGroup sourceGroup: sourceSet.getSourceGroups()) { FileObject result = tryGetTestFile(sourceGroup, relPath); if (result != null) { return result; } } return null; } public static FileObject tryGetTestFile(JavaExtension javaExt, String testClassName) { // Note that we always need '/' for FileObject (no matter the file system). String relPath = testClassName.replace('.', '/'); for (JavaSourceSet sourceSet: javaExt.getCurrentModel().getMainModule().getSources()) { FileObject result = tryGetTestFile(sourceSet, relPath); if (result != null) { return result; } } return null; } private FileObject tryGetTestFile() { return tryGetTestFile(javaExt, getTestClassName()); } private Action getJumpToSourcesAction() { return new JumpToSourcesAction(); } private Action getRerunTestAction() { return new RerunTestAction(); } private void jumpToSourcesNow() { final FileObject testFile = tryGetTestFile(); if (testFile == null) { return; } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { OpenEditorOutputListener.tryOpenFile(testFile, -1); } }); } @SuppressWarnings("serial") private class JumpToSourcesAction extends AbstractAction { public JumpToSourcesAction() { super(NbStrings.getJumpToSource()); } @Override public void actionPerformed(ActionEvent e) { NbTaskExecutors.DEFAULT_EXECUTOR.execute(Cancellation.UNCANCELABLE_TOKEN, new CancelableTask() { @Override public void execute(CancellationToken cancelToken) { jumpToSourcesNow(); } }, null); } } @SuppressWarnings("serial") private class RerunTestAction extends AbstractAction { public RerunTestAction() { super(NbStrings.getTestClassAgain()); } @Override public void actionPerformed(ActionEvent e) { Project project = javaExt.getProject(); Lookup context = Lookups.fixed(testTaskName, new SpecificTestClass(suiteName)); GradleActionProvider.invokeAction(project, ActionProvider.COMMAND_TEST_SINGLE, context); } } }