package name.admitriev.jhelper.configuration; import com.intellij.execution.ExecutionException; import com.intellij.execution.ProgramRunnerUtil; import com.intellij.execution.RunManager; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.runners.DefaultProgramRunner; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import name.admitriev.jhelper.exceptions.NotificationException; import name.admitriev.jhelper.generation.CodeGenerationUtils; import org.antlr.v4.runtime.misc.Nullable; import org.jetbrains.annotations.NotNull; import java.util.List; /** * Class for Running TaskConfiguration * It isn't fully compliant with {@link com.intellij.execution.runners.ProgramRunner} Interface because {@link #execute} doesn't call {@link RunProfile#getState} * as described in <a href="http://confluence.jetbrains.com/display/IDEADEV/Run+Configurations#RunConfigurations-RunningaProcess">IDEA DEV Confluence</a> */ public class TaskRunner extends DefaultProgramRunner { public static final String RUN_CONFIGURATION_NAME = "testrunner"; @NotNull @Override public String getRunnerId() { return "name.admitriev.jhelper.configuration.TaskRunner"; } @Override public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) { return profile instanceof TaskConfiguration; } /** * Runs specified TaskConfiguration: generates code and then runs output configuration. * * @throws ClassCastException if {@code environment.getRunProfile()} is not {@link TaskConfiguration}. * @throws ExecutionException if output configuration throws it. * @see ExecutionEnvironment#getRunProfile() */ @Override public void execute(@NotNull ExecutionEnvironment environment, @Nullable Callback callback) throws ExecutionException { Project project = environment.getProject(); TaskConfiguration taskConfiguration = (TaskConfiguration) environment.getRunProfile(); generateSubmissionFileForTask(project, taskConfiguration); generateRunFileForTask(project, taskConfiguration); List<RunnerAndConfigurationSettings> allSettings = RunManager.getInstance(project).getAllSettings(); RunnerAndConfigurationSettings outputSettings = null; for (RunnerAndConfigurationSettings configuration : allSettings) { if (configuration.getName().equals(RUN_CONFIGURATION_NAME)) { outputSettings = configuration; } } if (outputSettings == null) { throw new NotificationException("No run configuration found", "It should be called (" + RUN_CONFIGURATION_NAME + ")"); } ProgramRunnerUtil.executeConfiguration(project, outputSettings, environment.getExecutor()); } private static void generateRunFileForTask(Project project, TaskConfiguration taskConfiguration) { String pathToClassFile = taskConfiguration.getCppPath(); VirtualFile virtualFile = project.getBaseDir().findFileByRelativePath(pathToClassFile); if (virtualFile == null) { throw new NotificationException("Task file not found", "Seems your task is in inconsistent state"); } PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); if (psiFile == null) { throw new NotificationException("Couldn't get PSI file for input file"); } CodeGenerationUtils.generateRunFile(project, psiFile, taskConfiguration); } private static void generateSubmissionFileForTask(Project project, TaskConfiguration taskConfiguration) { String pathToClassFile = taskConfiguration.getCppPath(); VirtualFile virtualFile = project.getBaseDir().findFileByRelativePath(pathToClassFile); if (virtualFile == null) { throw new NotificationException("Task file not found", "Seems your task is in inconsistent state"); } PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); if (psiFile == null) { throw new NotificationException("Couldn't get PSI file for input file"); } CodeGenerationUtils.generateSubmissionFile(project, psiFile, taskConfiguration); } }