package org.netbeans.gradle.project.java.tasks;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Logger;
import org.gradle.util.GradleVersion;
import org.jtrim.cancel.Cancellation;
import org.jtrim.cancel.CancellationSource;
import org.jtrim.collections.CollectionsEx;
import org.jtrim.utils.ExceptionHelper;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.project.Project;
import org.netbeans.gradle.model.java.JavaTestTask;
import org.netbeans.gradle.model.util.Exceptions;
import org.netbeans.gradle.project.NbStrings;
import org.netbeans.gradle.project.api.config.GlobalConfig;
import org.netbeans.gradle.project.api.config.ProfileDef;
import org.netbeans.gradle.project.api.modelquery.GradleTarget;
import org.netbeans.gradle.project.api.task.BuiltInGradleCommandQuery;
import org.netbeans.gradle.project.api.task.CommandExceptionHider;
import org.netbeans.gradle.project.api.task.ContextAwareCommandAction;
import org.netbeans.gradle.project.api.task.ContextAwareCommandCompleteAction;
import org.netbeans.gradle.project.api.task.ContextAwareCommandCompleteListener;
import org.netbeans.gradle.project.api.task.ContextAwareCommandFinalizer;
import org.netbeans.gradle.project.api.task.CustomCommandActions;
import org.netbeans.gradle.project.api.task.ExecutedCommandContext;
import org.netbeans.gradle.project.api.task.GradleCommandTemplate;
import org.netbeans.gradle.project.api.task.GradleTargetVerifier;
import org.netbeans.gradle.project.api.task.SingleExecutionOutputProcessor;
import org.netbeans.gradle.project.api.task.TaskKind;
import org.netbeans.gradle.project.api.task.TaskOutputProcessor;
import org.netbeans.gradle.project.api.task.TaskVariable;
import org.netbeans.gradle.project.api.task.TaskVariableMap;
import org.netbeans.gradle.project.java.JavaExtension;
import org.netbeans.gradle.project.java.model.NbJavaModule;
import org.netbeans.gradle.project.java.properties.DebugMode;
import org.netbeans.gradle.project.java.test.TestTaskName;
import org.netbeans.gradle.project.java.test.TestXmlDisplayer;
import org.netbeans.gradle.project.output.DebugTextListener;
import org.netbeans.gradle.project.tasks.AttacherListener;
import org.netbeans.gradle.project.tasks.DebugUtils;
import org.netbeans.gradle.project.tasks.vars.StandardTaskVariable;
import org.netbeans.gradle.project.util.GradleVersions;
import org.netbeans.gradle.project.view.GlobalErrorReporter;
import org.netbeans.spi.project.ActionProvider;
import org.netbeans.spi.project.SingleMethod;
import org.openide.util.Lookup;
import org.openide.windows.OutputWriter;
public final class GradleJavaBuiltInCommands implements BuiltInGradleCommandQuery {
private static final Logger LOGGER = Logger.getLogger(GradleJavaBuiltInCommands.class.getName());
private static final String MAIN_CLASS_PROPERTY_NAME = "mainClass";
private static final String CMD_LINE_ARGS_PROPERTY_NAME = "cmdLineArgs";
private static final String JVM_LINE_ARGS_PROPERTY_NAME = "jvmLineArgs";
private static final String JPDA_PORT_PROPERTY_NAME = "debuggerJpdaPort";
private static final String DEBUGGED_TASK_PROPERTY_NAME = "debuggedTaskName";
public static final String TEST_WITH_COVERAGE = "test/coverage";
private static final CommandWithActions DEFAULT_BUILD_TASK = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList("build"),
Collections.<String>emptyList(),
true,
true);
private static final CommandWithActions DEFAULT_TEST_TASK = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList(cleanAndTestTasks()),
Collections.<String>emptyList(),
displayTestResults(),
hideTestFailures());
private static final CommandWithActions DEFAULT_TEST_WITH_COVERAGE_TASK = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList(cleanAndTestTasks(projectTask(JavaGradleTaskVariableQuery.COVERAGE_REPORT_TASK_NAME.getScriptReplaceConstant()))),
Arrays.asList("-PenableJacocoXmlReport=true"),
displayTestResults(),
hideTestFailures());
private static final CommandWithActions DEFAULT_RUN_TASK = blockingCommand(
TaskKind.RUN,
Arrays.asList(projectTask("run")),
Arrays.asList(cmdLineArg(), jvmLineArg()));
private static final CommandWithActions DEFAULT_DEBUG_TASK_1 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(projectTask("debug")),
Arrays.asList(cmdLineArg(), jvmLineArg()),
attachDebugger());
private static final CommandWithActions DEFAULT_DEBUG_TASK_2 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(projectTask("run")),
debuggeeAttachesArguments(projectTask("run"), cmdLineArg(), jvmLineArg()),
listenDebugger());
private static final CommandWithActions DEFAULT_JAVADOC_TASK = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList("javadoc"),
Collections.<String>emptyList());
private static final CommandWithActions DEFAULT_REBUILD_TASK = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList("clean", "build"),
Collections.<String>emptyList(),
true,
true);
private static final CommandWithActions DEFAULT_TEST_SINGLE_TASK_1 = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList(cleanAndTestTasks()),
Arrays.asList(testSingleArgument()),
displayTestResults(),
hideTestFailures());
private static final CommandWithActions DEFAULT_TEST_SINGLE_TASK_2 = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList(cleanAndTestClassTasks()),
Collections.<String>emptyList(),
displayTestResults(),
hideTestFailures());
private static final CommandWithActions DEFAULT_DEBUG_TEST_SINGLE_TASK_1 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(cleanAndTestTasks()),
Arrays.asList(testSingleArgument(), debugTestArgument()),
displayTestResults(),
hideTestFailures(),
attachDebugger());
private static final CommandWithActions DEFAULT_DEBUG_TEST_SINGLE_TASK_2 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(cleanAndTestTasks()),
debuggeeAttachesArguments(testTask(), testSingleArgument()),
displayTestResults(),
hideTestFailures(),
listenDebugger());
private static final CommandWithActions DEFAULT_DEBUG_TEST_SINGLE_TASK_3 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(cleanAndTestClassTasks()),
Arrays.asList(debugTestArgument()),
displayTestResults(),
hideTestFailures(),
attachDebugger());
private static final CommandWithActions DEFAULT_DEBUG_TEST_SINGLE_TASK_4 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(cleanAndTestClassTasks()),
debuggeeAttachesArguments(testTask()),
displayTestResults(),
hideTestFailures(),
listenDebugger());
private static final CommandWithActions DEFAULT_TEST_SINGLE_METHOD_TASK = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList(cleanAndTestMethodTasks()),
Collections.<String>emptyList(),
needsGradle("1.10"),
displayTestResults(),
hideTestFailures());
private static final CommandWithActions DEFAULT_DEBUG_TEST_SINGLE_METHOD_TASK_1 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(cleanAndTestMethodTasks()),
Arrays.asList(debugTestArgument()),
needsGradle("1.10"),
displayTestResults(),
hideTestFailures(),
attachDebugger());
private static final CommandWithActions DEFAULT_DEBUG_TEST_SINGLE_METHOD_TASK_2 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(cleanAndTestMethodTasks()),
debuggeeAttachesArguments(testTask()),
needsGradle("1.10"),
displayTestResults(),
hideTestFailures(),
listenDebugger());
private static final CommandWithActions DEFAULT_RUN_SINGLE_TASK = blockingCommand(
TaskKind.RUN,
Arrays.asList(projectTask("run")),
Arrays.asList(gradlePropertyArg(MAIN_CLASS_PROPERTY_NAME, StandardTaskVariable.SELECTED_CLASS.getVariable()), cmdLineArg(), jvmLineArg()),
true,
true);
private static final CommandWithActions DEFAULT_DEBUG_SINGLE_TASK_1 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(projectTask("debug")),
Arrays.asList(gradlePropertyArg(MAIN_CLASS_PROPERTY_NAME, StandardTaskVariable.SELECTED_CLASS.getVariable()), cmdLineArg(), jvmLineArg()),
true,
true,
attachDebugger());
private static final CommandWithActions DEFAULT_DEBUG_SINGLE_TASK_2 = blockingCommand(
TaskKind.DEBUG,
Arrays.asList(projectTask("run")),
debuggeeAttachesArguments(projectTask("run"), gradlePropertyArg(MAIN_CLASS_PROPERTY_NAME, StandardTaskVariable.SELECTED_CLASS.getVariable()), cmdLineArg(), jvmLineArg()),
true,
true,
listenDebugger());
private static final CommandWithActions DEFAULT_APPLY_CODE_CHANGES_TASK = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList(projectTask("classes")),
Collections.<String>emptyList(),
applyClassesActions());
private static final CommandWithActions DEFAULT_COMPILE_SINGLE_TASK = nonBlockingCommand(
TaskKind.BUILD,
Arrays.asList(projectTask("classes")),
Collections.<String>emptyList());
private static final Map<String, CommandWithActionsRef> DEFAULT_TASKS;
static {
DEFAULT_TASKS = new HashMap<>();
addToDefaults(ActionProvider.COMMAND_BUILD, DEFAULT_BUILD_TASK);
addToDefaults(ActionProvider.COMMAND_TEST, DEFAULT_TEST_TASK);
addToDefaults(TEST_WITH_COVERAGE, DEFAULT_TEST_WITH_COVERAGE_TASK);
addToDefaults(ActionProvider.COMMAND_RUN, DEFAULT_RUN_TASK);
addToDefaults(JavaProjectConstants.COMMAND_JAVADOC, DEFAULT_JAVADOC_TASK);
addToDefaults(ActionProvider.COMMAND_REBUILD, DEFAULT_REBUILD_TASK);
addToDefaults(SingleMethod.COMMAND_RUN_SINGLE_METHOD, DEFAULT_TEST_SINGLE_METHOD_TASK);
addToDefaults(ActionProvider.COMMAND_RUN_SINGLE, DEFAULT_RUN_SINGLE_TASK);
addToDefaults(JavaProjectConstants.COMMAND_DEBUG_FIX, DEFAULT_APPLY_CODE_CHANGES_TASK);
addToDefaults(ActionProvider.COMMAND_COMPILE_SINGLE, DEFAULT_COMPILE_SINGLE_TASK);
addToDefaults(ActionProvider.COMMAND_TEST_SINGLE, newSingleTestArgSelector(), Arrays.asList(
new CommandChoice<>(false, DEFAULT_TEST_SINGLE_TASK_1),
new CommandChoice<>(true, DEFAULT_TEST_SINGLE_TASK_2)
));
addToDefaults(ActionProvider.COMMAND_DEBUG_TEST_SINGLE, debugTestModeSelector(), Arrays.asList(
new CommandChoice<>(new DebugTestMode(false, DebugMode.DEBUGGER_ATTACHES), DEFAULT_DEBUG_TEST_SINGLE_TASK_1),
new CommandChoice<>(new DebugTestMode(false, DebugMode.DEBUGGER_LISTENS), DEFAULT_DEBUG_TEST_SINGLE_TASK_2),
new CommandChoice<>(new DebugTestMode(true, DebugMode.DEBUGGER_ATTACHES), DEFAULT_DEBUG_TEST_SINGLE_TASK_3),
new CommandChoice<>(new DebugTestMode(true, DebugMode.DEBUGGER_LISTENS), DEFAULT_DEBUG_TEST_SINGLE_TASK_4)
));
addToDefaults(SingleMethod.COMMAND_DEBUG_SINGLE_METHOD, debugModeSelector(), Arrays.asList(
new CommandChoice<>(DebugMode.DEBUGGER_ATTACHES, DEFAULT_DEBUG_TEST_SINGLE_METHOD_TASK_1),
new CommandChoice<>(DebugMode.DEBUGGER_LISTENS, DEFAULT_DEBUG_TEST_SINGLE_METHOD_TASK_2)
));
addToDefaults(ActionProvider.COMMAND_DEBUG, debugModeSelector(), Arrays.asList(
new CommandChoice<>(DebugMode.DEBUGGER_ATTACHES, DEFAULT_DEBUG_TASK_1),
new CommandChoice<>(DebugMode.DEBUGGER_LISTENS, DEFAULT_DEBUG_TASK_2)
));
addToDefaults(ActionProvider.COMMAND_DEBUG_SINGLE, debugModeSelector(), Arrays.asList(
new CommandChoice<>(DebugMode.DEBUGGER_ATTACHES, DEFAULT_DEBUG_SINGLE_TASK_1),
new CommandChoice<>(DebugMode.DEBUGGER_LISTENS, DEFAULT_DEBUG_SINGLE_TASK_2)
));
}
private static String cmdLineArg() {
return gradlePropertyArg(CMD_LINE_ARGS_PROPERTY_NAME, StandardTaskVariable.CMD_LINE_ARGS.getVariable());
}
private static String jvmLineArg() {
return gradlePropertyArg(JVM_LINE_ARGS_PROPERTY_NAME, StandardTaskVariable.JVM_LINE_ARGS.getVariable());
}
private static String gradlePropertyArg(String propertyName, TaskVariable taskVar) {
return gradlePropertyArg(propertyName, taskVar.getScriptReplaceConstant());
}
private static String gradlePropertyArg(String propertyName, String value) {
// TODO: Escape value
return "-P" + propertyName + "=" + value;
}
private static CommandSelector<Boolean> newSingleTestArgSelector() {
return new CommandSelector<Boolean>() {
@Override
public Boolean choose(JavaExtension javaExt) {
GradleTarget env = javaExt.getCurrentModel().getEvaluationEnvironment();
env.getGradleVersion();
return GradleVersions.VERSION_2_3.compareTo(env.getGradleVersion()) <= 0;
}
};
}
private static CommandSelector<DebugTestMode> debugTestModeSelector() {
final CommandSelector<DebugMode> debugModeSelector = debugModeSelector();
final CommandSelector<Boolean> newSingleTestArgSelector = newSingleTestArgSelector();
return new CommandSelector<DebugTestMode>() {
@Override
public DebugTestMode choose(JavaExtension javaExt) {
return new DebugTestMode(
newSingleTestArgSelector.choose(javaExt),
debugModeSelector.choose(javaExt));
}
};
}
private static CommandSelector<DebugMode> debugModeSelector() {
return new CommandSelector<DebugMode>() {
@Override
public DebugMode choose(JavaExtension javaExt) {
return javaExt.getProjectProperties().debugMode().getActiveValue();
}
};
}
private static <ChoiceType> void addToDefaults(
String command,
final CommandSelector<? extends ChoiceType> selector,
Collection<CommandChoice<ChoiceType>> choices) {
final List<CommandChoice<ChoiceType>> choicesCopy = CollectionsEx.readOnlyCopy(choices);
ExceptionHelper.checkNotNullArgument(selector, "selector");
ExceptionHelper.checkNotNullElements(choicesCopy, "choices");
DEFAULT_TASKS.put(command, new CommandWithActionsRef() {
@Override
public CommandWithActions get(JavaExtension javaExt) {
ChoiceType choice = selector.choose(javaExt);
for (CommandChoice<ChoiceType> candidate: choicesCopy) {
if (Objects.equals(candidate.getChoice(), choice)) {
return candidate.getCommandWithActions();
}
}
return choicesCopy.get(0).getCommandWithActions();
}
});
}
private static void addToDefaults(String command, final CommandWithActions task) {
DEFAULT_TASKS.put(command, new CommandWithActionsRef() {
@Override
public CommandWithActions get(JavaExtension javaExt) {
return task;
}
});
}
private static List<String> debuggeeAttachesArguments(String taskName, String... additionalArgs) {
List<String> result = new ArrayList<>(additionalArgs.length + 2);
result.addAll(Arrays.asList(additionalArgs));
result.add(gradlePropertyArg(DEBUGGED_TASK_PROPERTY_NAME, taskName));
result.add(gradlePropertyArg(JPDA_PORT_PROPERTY_NAME, DebuggerServiceFactory.JPDA_PORT_VAR));
return result;
}
private static String debugTestArgument() {
return "-D" + JavaGradleTaskVariableQuery.TEST_TASK_NAME.getScriptReplaceConstant() + ".debug";
}
private static String testSingleArgument() {
StringBuilder result = new StringBuilder(64);
result.append("-D");
result.append(JavaGradleTaskVariableQuery.TEST_TASK_NAME.getScriptReplaceConstant());
result.append(".single=");
result.append(StandardTaskVariable.TEST_FILE_PATH.getScriptReplaceConstant());
return result.toString();
}
private static String cleanTestTask() {
return projectTask("clean" + JavaGradleTaskVariableQuery.TEST_TASK_NAME_CAPITAL.getScriptReplaceConstant());
}
private static String testTask() {
return projectTask(JavaGradleTaskVariableQuery.TEST_TASK_NAME.getScriptReplaceConstant());
}
private static String[] cleanAndTestClassTasks() {
return cleanAndTestTasks("--tests", StandardTaskVariable.SELECTED_CLASS.getScriptReplaceConstant() + "*");
}
private static String[] cleanAndTestMethodTasks() {
return cleanAndTestTasks("--tests", StandardTaskVariable.TEST_METHOD.getScriptReplaceConstant());
}
private static String[] cleanAndTestTasks(String... testTaskOptions) {
String[] result = new String[testTaskOptions.length + 2];
result[0] = cleanTestTask();
result[1] = testTask();
System.arraycopy(testTaskOptions, 0, result, 2, testTaskOptions.length);
return result;
}
private static String projectTask(String task) {
return StandardTaskVariable.PROJECT_PATH_NORMALIZED.getScriptReplaceConstant() + ":" + task;
}
private final JavaExtension javaExt;
private final Set<String> supportedCommands;
public GradleJavaBuiltInCommands(JavaExtension javaExt) {
ExceptionHelper.checkNotNullArgument(javaExt, "javaExt");
this.javaExt = javaExt;
this.supportedCommands = Collections.unmodifiableSet(DEFAULT_TASKS.keySet());
}
@Override
public Set<String> getSupportedCommands() {
return supportedCommands;
}
@Override
public String tryGetDisplayNameOfCommand(String command) {
if (TEST_WITH_COVERAGE.equals(command)) {
return NbStrings.getTestWithCoverageCommandCaption();
}
// The contract of this method allows us to rely on the defaults.
return null;
}
private CommandWithActions tryGetDefaultCommandWithActions(String command) {
CommandWithActionsRef ref = DEFAULT_TASKS.get(command);
return ref != null ? ref.get(javaExt) : null;
}
@Override
public GradleCommandTemplate tryGetDefaultGradleCommand(ProfileDef profileDef, String command) {
CommandWithActions task = tryGetDefaultCommandWithActions(command);
return task != null ? task.getCommand() : null;
}
@Override
public CustomCommandActions tryGetCommandDefs(ProfileDef profileDef, String command) {
CommandWithActions task = tryGetDefaultCommandWithActions(command);
return task != null ? task.getCustomActions(javaExt) : null;
}
private static boolean isTestFailureException(Throwable taskError) {
if (!(taskError instanceof Exception)) {
return false;
}
Throwable rootCause = Exceptions.getRootCause(taskError);
String message = rootCause.getMessage();
if (message == null) {
return false;
}
message = message.toLowerCase(Locale.ROOT);
return message.contains("there were failing tests");
}
private static CommandExceptionHider testFailureHider() {
return new CommandExceptionHider() {
@Override
public boolean hideException(Throwable taskError) {
return isTestFailureException(taskError);
}
};
}
private static CustomCommandAdjuster hideTestFailures() {
return new CustomCommandAdjuster() {
@Override
public void adjust(JavaExtension javaExt, CustomCommandActions.Builder customActions) {
customActions.setCommandExceptionHider(testFailureHider());
}
};
}
private static String removeLeadingColons(String str) {
if (!str.startsWith(":")) {
return str;
}
int i;
for (i = 0; i < str.length(); i++) {
if (str.charAt(i) != ':') {
break;
}
}
return str.substring(i);
}
private static String tryRelativizeTaskName(String projectPath, String taskName) {
if (taskName.startsWith(":")) {
if (!taskName.startsWith(projectPath)) {
return null;
}
return removeLeadingColons(taskName.substring(projectPath.length()));
}
else {
return taskName;
}
}
private static List<String> filterTestTaskNames(JavaExtension javaExt, List<String> taskNames) {
NbJavaModule mainModule = javaExt.getCurrentModel().getMainModule();
List<String> result = new ArrayList<>();
for (String taskName: taskNames) {
String projectPath = mainModule.getProperties().getProjectFullName();
String relativeTaskName = tryRelativizeTaskName(projectPath, taskName);
if (relativeTaskName != null) {
JavaTestTask testTask = mainModule.tryGetTestModelByName(relativeTaskName);
if (testTask != null) {
result.add(testTask.getName());
}
}
}
return result;
}
private static List<String> getTestNames(JavaExtension javaExt, ExecutedCommandContext executedCommandContext) {
List<String> requestedTaskNames = filterTestTaskNames(javaExt, executedCommandContext.getTaskNames());
if (!requestedTaskNames.isEmpty()) {
return requestedTaskNames;
}
TaskVariableMap variables = executedCommandContext.getTaskVariables();
String value = variables.tryGetValueForVariable(JavaGradleTaskVariableQuery.TEST_TASK_NAME);
if (value == null) {
LOGGER.warning("Could not find test task name variable.");
value = TestTaskName.DEFAULT_TEST_TASK_NAME;
}
return Collections.singletonList(value);
}
private static ContextAwareCommandCompleteListener displayTestResults(
final Project project,
final JavaExtension javaExt,
final Lookup startContext) {
return new ContextAwareCommandCompleteListener() {
@Override
public void onComplete(ExecutedCommandContext executedCommandContext, Throwable error) {
displayTestReports(project, javaExt, executedCommandContext, startContext, error);
}
};
}
private static void displayErrorDueToNoTestReportsFound(TestXmlDisplayer xmlDisplayer) {
String message = NbStrings.getErrorDueToNoTestReportsFound(
xmlDisplayer.getTestName(),
xmlDisplayer.tryGetReportDirectory());
GlobalErrorReporter.showIssue(message);
}
private static void displayTestReports(
Project project,
JavaExtension javaExt,
ExecutedCommandContext executedCommandContext,
Lookup startContext,
Throwable error) {
List<String> testNames = getTestNames(javaExt, executedCommandContext);
for (String testName: testNames) {
TestXmlDisplayer xmlDisplayer = new TestXmlDisplayer(project, testName);
if (!xmlDisplayer.displayReport(startContext)) {
if (error == null) {
displayErrorDueToNoTestReportsFound(xmlDisplayer);
}
}
}
}
private static ContextAwareCommandCompleteAction displayTestAction(final JavaExtension javaExt) {
return new ContextAwareCommandCompleteAction() {
@Override
public ContextAwareCommandCompleteListener startCommand(Project project, Lookup commandContext) {
return displayTestResults(project, javaExt, commandContext);
}
};
}
private static CustomCommandAdjuster displayTestResults() {
return new CustomCommandAdjuster() {
@Override
public void adjust(JavaExtension javaExt, CustomCommandActions.Builder customActions) {
customActions.setContextAwareFinalizer(displayTestAction(javaExt));
}
};
}
private static CustomCommandAdjuster needsGradle(String minGradleVersionStr) {
final GradleVersion minGradleVersion = GradleVersion.version(minGradleVersionStr);
return new CustomCommandAdjuster() {
@Override
public void adjust(JavaExtension javaExt, CustomCommandActions.Builder customActions) {
customActions.setGradleTargetVerifier(new GradleTargetVerifier() {
@Override
public boolean checkTaskExecutable(
GradleTarget gradleTarget,
OutputWriter output,
OutputWriter errOutput) {
if (gradleTarget.getGradleVersion().compareTo(minGradleVersion) < 0) {
errOutput.println(NbStrings.getNeedsMinGradleVersion(minGradleVersion));
return false;
}
return true;
}
});
}
};
}
private static SingleExecutionOutputProcessor attachDebuggerListener(
final JavaExtension javaExt,
CustomCommandActions.Builder customActions) {
final CancellationSource cancel = Cancellation.createCancellationSource();
customActions.setCancelToken(cancel.getToken());
return new SingleExecutionOutputProcessor() {
@Override
public TaskOutputProcessor startExecution(Project project) {
return new DebugTextListener(new AttacherListener(javaExt, cancel.getController()));
}
};
}
private static CustomCommandAdjuster listenDebugger() {
return new CustomCommandAdjuster() {
@Override
public void adjust(JavaExtension javaExt, CustomCommandActions.Builder customActions) {
customActions.setCommandServiceFactory(new DebuggerServiceFactory(javaExt));
}
};
}
private static CustomCommandAdjuster attachDebugger() {
return new CustomCommandAdjuster() {
@Override
public void adjust(JavaExtension javaExt, CustomCommandActions.Builder customActions) {
customActions.setSingleExecutionStdOutProcessor(attachDebuggerListener(javaExt, customActions));
}
};
}
private static ContextAwareCommandFinalizer applyClassesFinalizer(final Project project, final String className) {
return new ContextAwareCommandFinalizer() {
@Override
public void finalizeSuccessfulCommand(OutputWriter output, OutputWriter errOutput) {
DebugUtils.applyChanges(project, output, className);
}
};
}
private static CustomCommandAdjuster applyClassesActions() {
return new CustomCommandAdjuster() {
@Override
public void adjust(JavaExtension javaExt, CustomCommandActions.Builder customActions) {
customActions.setContextAwareAction(new ContextAwareCommandAction() {
@Override
public ContextAwareCommandFinalizer startCommand(Project project, Lookup commandContext) {
String className = DebugUtils.getActiveClassName(project, commandContext);
return applyClassesFinalizer(project, className);
}
});
}
};
}
private static CommandWithActions blockingCommand(
TaskKind taskKind,
List<String> taskNames,
List<String> arguments,
CustomCommandAdjuster... adjusters) {
return blockingCommand(taskKind, taskNames, arguments, false, false, adjusters);
}
private static CommandWithActions blockingCommand(
TaskKind taskKind,
List<String> taskNames,
List<String> arguments,
boolean skipTestsIfNeeded,
boolean skipCheckIfNeeded,
CustomCommandAdjuster... adjusters) {
GradleCommandTemplate.Builder commandBuilder = new GradleCommandTemplate.Builder("", taskNames);
commandBuilder.setArguments(arguments);
commandBuilder.setBlocking(true);
return new CommandWithActions(taskKind, commandBuilder.create(), adjusters, skipTestsIfNeeded, skipCheckIfNeeded);
}
private static CommandWithActions nonBlockingCommand(
TaskKind taskKind,
List<String> taskNames,
List<String> arguments,
CustomCommandAdjuster... adjusters) {
return nonBlockingCommand(taskKind, taskNames, arguments, false, false, adjusters);
}
private static CommandWithActions nonBlockingCommand(
TaskKind taskKind,
List<String> taskNames,
List<String> arguments,
boolean skipTestsIfNeeded,
boolean skipCheckIfNeeded,
CustomCommandAdjuster... adjusters) {
GradleCommandTemplate.Builder commandBuilder = new GradleCommandTemplate.Builder("", taskNames);
commandBuilder.setArguments(arguments);
commandBuilder.setBlocking(false);
return new CommandWithActions(taskKind, commandBuilder.create(), adjusters, skipTestsIfNeeded, skipCheckIfNeeded);
}
private static CustomCommandActions createCustomActions(
TaskKind taskKind, JavaExtension javaExt, CustomCommandAdjuster... adjusters) {
if (adjusters.length == 0) {
return CustomCommandActions.simpleAction(taskKind);
}
CustomCommandActions.Builder result = new CustomCommandActions.Builder(taskKind);
for (CustomCommandAdjuster adjuster: adjusters) {
adjuster.adjust(javaExt, result);
}
return result.create();
}
private static final class CommandChoice<ChoiceType> {
private final ChoiceType choice;
private final CommandWithActions commandWithActions;
public CommandChoice(ChoiceType choice, CommandWithActions commandWithActions) {
ExceptionHelper.checkNotNullArgument(choice, "choice");
ExceptionHelper.checkNotNullArgument(commandWithActions, "commandWithActions");
this.choice = choice;
this.commandWithActions = commandWithActions;
}
public ChoiceType getChoice() {
return choice;
}
public CommandWithActions getCommandWithActions() {
return commandWithActions;
}
}
private static interface CommandSelector<ChoiceType> {
public ChoiceType choose(JavaExtension javaExt);
}
private static interface CommandWithActionsRef {
public CommandWithActions get(JavaExtension javaExt);
}
private static final class CommandWithActions {
private final TaskKind taskKind;
private final GradleCommandTemplate command;
private final CustomCommandAdjuster[] customActions;
private final boolean skipTestsIfNeeded;
private final boolean skipCheckIfNeeded;
public CommandWithActions(
TaskKind taskKind,
GradleCommandTemplate command,
CustomCommandAdjuster[] customActions,
boolean skipTestIfNeeded,
boolean skipCheckIfNeeded) {
this.taskKind = taskKind;
this.command = command;
this.customActions = customActions.clone();
this.skipTestsIfNeeded = skipTestIfNeeded;
this.skipCheckIfNeeded = skipCheckIfNeeded;
}
public GradleCommandTemplate getCommand() {
boolean skipTests = skipTestsIfNeeded && GlobalConfig.skipTests().getValue();
boolean skipCheck = skipCheckIfNeeded && GlobalConfig.skipCheck().getValue();
if (skipTests || skipCheck) {
GradleCommandTemplate.Builder builder = new GradleCommandTemplate.Builder(command);
List<String> prevArguments = command.getArguments();
List<String> newArguments = new ArrayList<>(prevArguments.size() + 4);
newArguments.addAll(prevArguments);
if (skipTests) {
newArguments.add("-x");
newArguments.add(TestTaskName.DEFAULT_TEST_TASK_NAME);
}
if (skipCheck) {
newArguments.add("-x");
newArguments.add("check");
}
builder.setArguments(newArguments);
return builder.create();
}
return command;
}
public CustomCommandActions getCustomActions(JavaExtension javaExt) {
return createCustomActions(taskKind, javaExt, customActions);
}
}
private interface CustomCommandAdjuster {
public void adjust(JavaExtension javaExt, CustomCommandActions.Builder customActions);
}
private static final class DebugTestMode {
private final boolean mayUseNewTestArgument;
private final DebugMode debugMode;
public DebugTestMode(boolean mayUseNewTestArgument, DebugMode debugMode) {
this.mayUseNewTestArgument = mayUseNewTestArgument;
this.debugMode = debugMode;
}
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + (mayUseNewTestArgument ? 1 : 0);
hash = 97 * hash + Objects.hashCode(debugMode);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
final DebugTestMode other = (DebugTestMode)obj;
return this.mayUseNewTestArgument == other.mayUseNewTestArgument
&& this.debugMode == other.debugMode;
}
}
}