IDEA-120860 Gradle: apply grails facets/view on grails project import

This commit is contained in:
Vladislav.Soroka
2014-06-24 16:32:10 +04:00
parent 5adcafb458
commit c62ad6a6ff
28 changed files with 611 additions and 103 deletions
@@ -21,6 +21,7 @@ import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTask;
@@ -50,4 +51,6 @@ public interface ExternalSystemExecutionConsoleManager<ExternalSystemRunConfigur
void onOutput(@NotNull String text, @NotNull Key processOutputType);
boolean isApplicableFor(@NotNull ExternalSystemTask task);
AnAction[] getRestartActions();
}
@@ -21,6 +21,7 @@ import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -39,11 +40,21 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
private List<String> myTaskNames = ContainerUtilRt.newArrayList();
private List<String> myTaskDescriptions = ContainerUtilRt.newArrayList();
@Nullable private String myExecutionName;
private String myExternalSystemIdString;
private String myExternalProjectPath;
private String myVmOptions;
private String myScriptParameters;
@Nullable
public String getExecutionName() {
return myExecutionName;
}
public void setExecutionName(@Nullable String executionName) {
myExecutionName = executionName;
}
public String getExternalSystemIdString() {
return myExternalSystemIdString;
}
@@ -99,6 +110,7 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
@Override
public ExternalSystemTaskExecutionSettings clone() {
ExternalSystemTaskExecutionSettings result = new ExternalSystemTaskExecutionSettings();
result.setExecutionName(getExecutionName());
result.setExternalSystemIdString(getExternalSystemIdString());
result.setExternalProjectPath(getExternalProjectPath());
result.setVmOptions(getVmOptions());
@@ -111,6 +123,7 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
@Override
public int hashCode() {
int result = myTaskNames != null ? myTaskNames.hashCode() : 0;
result = 31 * result + (myExecutionName != null ? myExecutionName.hashCode() : 0);
result = 31 * result + (myExternalSystemIdString != null ? myExternalSystemIdString.hashCode() : 0);
result = 31 * result + (myExternalProjectPath != null ? myExternalProjectPath.hashCode() : 0);
result = 31 * result + (myVmOptions != null ? myVmOptions.hashCode() : 0);
@@ -125,6 +138,10 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
ExternalSystemTaskExecutionSettings settings = (ExternalSystemTaskExecutionSettings)o;
if (myExecutionName != null ? !myExecutionName.equals(settings.myExecutionName) : settings.myExecutionName != null) {
return false;
}
if (myExternalProjectPath != null
? !myExternalProjectPath.equals(settings.myExternalProjectPath)
: settings.myExternalProjectPath != null)
@@ -48,6 +48,14 @@ public interface ExternalSystemTaskNotificationListener {
*/
void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut);
///**
// * Notifies about stdin during the task execution
// *
// * @param id id of the task being executed
// * @param text text produced by external system during the target task execution
// */
//void onTaskInput(@NotNull ExternalSystemTaskId id, @NotNull String text);
/**
* Notifies that task with the given id is finished.
*
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.task;
/**
* @author Vladislav.Soroka
* @since 6/19/2014
*/
public interface TaskCallback {
void onSuccess();
void onFailure();
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.task;
/**
* @author Vladislav.Soroka
* @since 6/19/2014
*/
public class TaskCallbackAdapter implements TaskCallback {
@Override
public void onSuccess() {}
@Override
public void onFailure() {}
}
@@ -33,6 +33,7 @@ import com.intellij.openapi.externalSystem.service.ParametersEnhancer;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.OrderRootType;
@@ -49,10 +50,10 @@ import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.TransferToEDTQueue;
import com.intellij.util.lang.UrlClassLoader;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -665,4 +666,14 @@ public class ExternalSystemApiUtil {
//noinspection unchecked
return (T)loader.loadClass(clazz.getName()).newInstance();
}
@Contract("_, null -> false")
public static boolean isExternalSystemAwareModule(@NotNull ProjectSystemId systemId, @Nullable Module module) {
return module != null && systemId.getId().equals(module.getOptionValue(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY));
}
@Nullable
public static String getExternalProjectPath(@Nullable Module module) {
return module != null ? module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY) : null;
}
}
@@ -109,7 +109,9 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
@NotNull
public static String generateName(@NotNull Project project, @NotNull ExternalSystemTaskExecutionSettings settings) {
return generateName(project, settings.getExternalSystemId(), settings.getExternalProjectPath(), settings.getTaskNames());
return generateName(
project, settings.getExternalSystemId(), settings.getExternalProjectPath(), settings.getTaskNames(), settings.getExecutionName()
);
}
@NotNull
@@ -121,8 +123,16 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
public static String generateName(@NotNull Project project,
@NotNull ProjectSystemId externalSystemId,
@Nullable String externalProjectPath,
@NotNull List<String> taskNames)
{
@NotNull List<String> taskNames) {
return generateName(project, externalSystemId, externalProjectPath, taskNames, null);
}
@NotNull
public static String generateName(@NotNull Project project,
@NotNull ProjectSystemId externalSystemId,
@Nullable String externalProjectPath,
@NotNull List<String> taskNames,
@Nullable String executionName) {
ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
assert manager != null;
AbstractExternalSystemSettings<?, ?,?> s = manager.getSettingsProvider().fun(project);
@@ -168,12 +178,16 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
}
buffer.append("[");
if (!taskNames.isEmpty()) {
if (!StringUtil.isEmpty(executionName)) {
buffer.append(executionName);
}
else if (!taskNames.isEmpty()) {
for (String taskName : taskNames) {
buffer.append(taskName).append(" ");
}
buffer.setLength(buffer.length() - 1);
}
buffer.append("]");
return buffer.toString();
@@ -22,6 +22,7 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.externalSystem.execution.ExternalSystemExecutionConsoleManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTask;
@@ -67,4 +68,9 @@ public class DefaultExternalSystemExecutionConsoleManager implements ExternalSys
public boolean isApplicableFor(@NotNull ExternalSystemTask task) {
return true;
}
@Override
public AnAction[] getRestartActions() {
return new AnAction[0];
}
}
@@ -43,8 +43,7 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.OutputStream;
import java.io.*;
import java.util.List;
/**
@@ -236,12 +235,15 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase {
});
}
});
return new DefaultExecutionResult(consoleView, processHandler);
DefaultExecutionResult result = new DefaultExecutionResult(consoleView, processHandler);
result.setRestartActions(consoleManager.getRestartActions());
return result;
}
}
private static class MyProcessHandler extends ProcessHandler {
private final ExternalSystemExecuteTaskTask myTask;
@Nullable private volatile OutputStream myOutputStream;
public MyProcessHandler(ExternalSystemExecuteTaskTask task) {
myTask = task;
@@ -208,6 +208,8 @@ public class ExternalSystemTasksTree extends Tree implements Producer<ExternalTa
taskExecutionSettings.setExternalProjectPath(executionSettings.getExternalProjectPath());
taskExecutionSettings.setExternalSystemIdString(executionSettings.getExternalSystemIdString());
taskExecutionSettings.setVmOptions(executionSettings.getVmOptions());
taskExecutionSettings.setScriptParameters(executionSettings.getScriptParameters());
taskExecutionSettings.setExecutionName(executionSettings.getExecutionName());
executionInfo = new ExternalTaskExecutionInfo(taskExecutionSettings, taskExecutionInfo.getExecutorId());
map.put(key, executionInfo);
}
@@ -19,9 +19,13 @@ import com.intellij.execution.*;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.rmi.RemoteUtil;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.Application;
@@ -58,6 +62,7 @@ import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemRecentT
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.externalSystem.task.TaskCallback;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -67,7 +72,9 @@ import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -83,6 +90,7 @@ import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.UIUtil;
@@ -539,23 +547,120 @@ public class ExternalSystemUtil {
@NotNull String executorId,
@NotNull Project project,
@NotNull ProjectSystemId externalSystemId) {
runTask(taskSettings, executorId, project, externalSystemId, null);
runTask(taskSettings, executorId, project, externalSystemId, null, ProgressExecutionMode.IN_BACKGROUND_ASYNC);
}
public static void runTask(@NotNull ExternalSystemTaskExecutionSettings taskSettings,
@NotNull String executorId,
@NotNull Project project,
@NotNull ProjectSystemId externalSystemId,
@Nullable ProgramRunner.Callback callback) {
public static void runTask(@NotNull final ExternalSystemTaskExecutionSettings taskSettings,
@NotNull final String executorId,
@NotNull final Project project,
@NotNull final ProjectSystemId externalSystemId,
@Nullable final TaskCallback callback,
@NotNull final ProgressExecutionMode progressExecutionMode) {
final Pair<ProgramRunner, ExecutionEnvironment> pair = createRunner(taskSettings, executorId, project, externalSystemId);
if (pair == null) return;
try {
pair.first.execute(pair.second, callback);
}
catch (ExecutionException e) {
LOG.warn("Can't execute task " + taskSettings, e);
}
final ProgramRunner runner = pair.first;
final ExecutionEnvironment environment = pair.second;
final TaskUnderProgress task = new TaskUnderProgress() {
@Override
public void execute(@NotNull ProgressIndicator indicator) {
final Semaphore targetDone = new Semaphore();
final Ref<Boolean> result = new Ref<Boolean>(false);
final Disposable disposable = Disposer.newDisposable();
project.getMessageBus().connect(disposable).subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() {
public void processStartScheduled(final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
targetDone.down();
}
}
public void processNotStarted(final String executorIdLocal, @NotNull final ExecutionEnvironment environmentLocal) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
targetDone.up();
}
}
public void processStarted(final String executorIdLocal,
@NotNull final ExecutionEnvironment environmentLocal,
@NotNull final ProcessHandler handler) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
handler.addProcessListener(new ProcessAdapter() {
public void processTerminated(ProcessEvent event) {
result.set(event.getExitCode() == 0);
targetDone.up();
}
});
}
}
});
try {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
try {
runner.execute(environment);
}
catch (ExecutionException e) {
targetDone.up();
LOG.error(e);
}
}
}, ModalityState.NON_MODAL);
}
catch (Exception e) {
LOG.error(e);
Disposer.dispose(disposable);
return;
}
targetDone.waitFor();
Disposer.dispose(disposable);
if (callback != null) {
if (result.get()) {
callback.onSuccess();
}
else {
callback.onFailure();
}
}
}
};
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
final String title = AbstractExternalSystemTaskConfigurationType.generateName(project, taskSettings);
switch (progressExecutionMode) {
case MODAL_SYNC:
new Task.Modal(project, title, true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
task.execute(indicator);
}
}.queue();
break;
case IN_BACKGROUND_ASYNC:
new Task.Backgroundable(project, title) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
task.execute(indicator);
}
}.queue();
break;
case START_IN_FOREGROUND_ASYNC:
new Task.Backgroundable(project, title, true, PerformInBackgroundOption.DEAF) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
task.execute(indicator);
}
}.queue();
}
}
});
}
@Nullable
@@ -579,7 +684,11 @@ public class ExternalSystemUtil {
RunnerAndConfigurationSettings settings = RunManager.getInstance(project).createRunConfiguration(name, configurationType.getFactory());
ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)settings.getConfiguration();
runConfiguration.getSettings().setExternalProjectPath(taskSettings.getExternalProjectPath());
runConfiguration.getSettings().setTaskNames(taskSettings.getTaskNames());
runConfiguration.getSettings().setTaskNames(ContainerUtil.newArrayList(taskSettings.getTaskNames()));
runConfiguration.getSettings().setTaskDescriptions(ContainerUtil.newArrayList(taskSettings.getTaskDescriptions()));
runConfiguration.getSettings().setVmOptions(taskSettings.getVmOptions());
runConfiguration.getSettings().setScriptParameters(taskSettings.getScriptParameters());
runConfiguration.getSettings().setExecutionName(taskSettings.getExecutionName());
return Pair.create(runner, new ExecutionEnvironment(executor, runner, settings, project));
}
@@ -30,9 +30,7 @@ import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecution
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemProcessingManager;
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver;
import com.intellij.openapi.externalSystem.service.project.autoimport.CachingExternalSystemAutoImportAware;
@@ -53,6 +51,8 @@ import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.PathUtil;
import com.intellij.util.PathsList;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.messages.MessageBusConnection;
import icons.GradleIcons;
@@ -74,11 +74,7 @@ import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.*;
/**
* @author Denis Zhdanov
@@ -198,9 +194,20 @@ public class GradleManager
@Override
public void enhanceRemoteProcessing(@NotNull SimpleJavaParameters parameters) throws ExecutionException {
final Set<String> additionalEntries = ContainerUtilRt.newHashSet();
for (GradleProjectResolverExtension extension : RESOLVER_EXTENSIONS.getValue()) {
ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(extension.getClass()));
for (Class aClass : extension.getExtraProjectModelClasses()) {
ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(aClass));
}
extension.enhanceRemoteProcessing(parameters);
}
final PathsList classPath = parameters.getClassPath();
for (String entry : additionalEntries) {
classPath.add(entry);
}
parameters.getVMParametersList().addProperty(
ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY, GradleConstants.SYSTEM_ID.getId());
}
@@ -79,7 +79,7 @@ public class GradleScriptType extends GroovyRunnableScriptType {
private static final Pattern MAIN_CLASS_NAME_PATTERN = Pattern.compile("\nSTARTER_MAIN_CLASS=(.*)\n");
public static final GroovyScriptType INSTANCE = new GradleScriptType();
public static final GradleScriptType INSTANCE = new GradleScriptType();
private GradleScriptType() {
super(GradleConstants.EXTENSION);
@@ -264,7 +264,7 @@ public class GradleScriptType extends GroovyRunnableScriptType {
if (scriptPath == null) {
throw new CantRunException("Target script is undefined");
}
params.getProgramParametersList().add("--build-file");
params.getProgramParametersList().add("--project-dir");
params.getProgramParametersList().add(FileUtil.toSystemDependentName(scriptPath));
params.getProgramParametersList().addParametersString(configuration.getProgramParameters());
params.getProgramParametersList().addParametersString(scriptParameters);
@@ -273,7 +273,7 @@ public class GradleScriptType extends GroovyRunnableScriptType {
}
@NotNull
private static String findMainClass(VirtualFile gradleHome, VirtualFile script, Project project) {
private static String findMainClass(VirtualFile gradleHome, @Nullable VirtualFile script, Project project) {
final String userDefined = System.getProperty("gradle.launcher.class");
if (StringUtil.isNotEmpty(userDefined)) {
return userDefined;
@@ -298,9 +298,12 @@ public class GradleScriptType extends GroovyRunnableScriptType {
}
}
final PsiFile grFile = PsiManager.getInstance(project).findFile(script);
if (grFile != null && JavaPsiFacade.getInstance(project).findClass("org.gradle.BootstrapMain", grFile.getResolveScope()) != null) {
return "org.gradle.BootstrapMain";
final PsiFile grFile;
if (script != null) {
grFile = PsiManager.getInstance(project).findFile(script);
if (grFile != null && JavaPsiFacade.getInstance(project).findClass("org.gradle.BootstrapMain", grFile.getResolveScope()) != null) {
return "org.gradle.BootstrapMain";
}
}
return "org.gradle.launcher.GradleMain";
@@ -27,6 +27,7 @@ import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView;
import com.intellij.execution.testframework.sm.runner.ui.TestTreeRenderer;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.execution.ExternalSystemExecutionConsoleManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
@@ -193,4 +194,9 @@ public class GradleTestsExecutionConsoleManager implements ExternalSystemExecuti
}
return false;
}
@Override
public AnAction[] getRestartActions() {
return new AnAction[0];
}
}
@@ -26,6 +26,7 @@ import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.openapi.util.KeyValue;
import com.intellij.util.Consumer;
import org.gradle.tooling.model.idea.IdeaModule;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -54,7 +55,7 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
}
@Override
public void setNext(@Nullable GradleProjectResolverExtension next) {
public void setNext(@NotNull GradleProjectResolverExtension next) {
// there always should be at least gradle basic resolver further in the chain
//noinspection ConstantConditions
assert next != null;
@@ -131,6 +132,12 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
return Collections.emptySet();
}
@NotNull
@Override
public Set<Class> getToolingExtensionsClasses() {
return Collections.emptySet();
}
@NotNull
@Override
public List<KeyValue<String, String>> getExtraJvmArgs() {
@@ -162,4 +169,10 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
@Override
public void preImportCheck() {
}
@Override
public void enhanceTaskProcessing(@NotNull List<String> taskNames,
@Nullable String debuggerSetup,
@NotNull Consumer<String> initScriptConsumer) {
}
}
@@ -37,10 +37,7 @@ import com.intellij.openapi.util.KeyValue;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.BooleanFunction;
import com.intellij.util.Function;
import com.intellij.util.PathUtil;
import com.intellij.util.PathsList;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.net.HttpConfigurable;
@@ -59,6 +56,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.*;
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
import org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl;
import org.jetbrains.plugins.gradle.tooling.internal.init.Init;
import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
@@ -91,7 +89,7 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
}
@Override
public void setNext(@Nullable GradleProjectResolverExtension next) {
public void setNext(@NotNull GradleProjectResolverExtension next) {
// should be the last extension in the chain
}
@@ -324,6 +322,17 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
GradleBuild.class, ModuleExtendedModel.class, BuildScriptClasspathModel.class);
}
@NotNull
@Override
public Set<Class> getToolingExtensionsClasses() {
return ContainerUtil.<Class>set(
// gradle-tooling-extension-api jar
ProjectImportAction.class,
// gradle-tooling-extension-impl jar
ModelBuildScriptClasspathBuilderImpl.class
);
}
@NotNull
@Override
public List<KeyValue<String, String>> getExtraJvmArgs() {
@@ -360,6 +369,23 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
public void preImportCheck() {
}
@Override
public void enhanceTaskProcessing(@NotNull List<String> taskNames,
@Nullable String debuggerSetup,
@NotNull Consumer<String> initScriptConsumer) {
if (!StringUtil.isEmpty(debuggerSetup)) {
final String[] lines = {
"gradle.taskGraph.beforeTask { Task task ->",
" if (task instanceof JavaForkOptions) {",
" task.jvmArgs '" + debuggerSetup.trim() + '\'',
" }" +
"}",
};
final String script = StringUtil.join(lines, SystemProperties.getLineSeparator());
initScriptConsumer.consume(script);
}
}
@Override
public void enhanceRemoteProcessing(@NotNull SimpleJavaParameters parameters) throws ExecutionException {
PathsList classPath = parameters.getClassPath();
@@ -47,7 +47,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.*;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
@@ -382,14 +385,15 @@ public class GradleExecutionHelper {
}
@Nullable
public static File generateInitScript(boolean isBuildSrcProject) {
public static File generateInitScript(boolean isBuildSrcProject, @NotNull Set<Class> toolingExtensionClasses) {
InputStream stream = Init.class.getResourceAsStream("/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle");
try {
if (stream == null) {
LOG.warn("Can't get init script template");
return null;
}
String s = FileUtil.loadTextAndClose(stream).replaceFirst(Pattern.quote("${EXTENSIONS_JARS_PATH}"), getToolingExtensionsJarPaths());
final String toolingExtensionsJarPaths = getToolingExtensionsJarPaths(toolingExtensionClasses);
String s = FileUtil.loadTextAndClose(stream).replaceFirst(Pattern.quote("${EXTENSIONS_JARS_PATH}"), toolingExtensionsJarPaths);
if (isBuildSrcProject) {
String buildSrcDefaultInitScript = getBuildSrcDefaultInitScript();
if (buildSrcDefaultInitScript == null) return null;
@@ -482,17 +486,10 @@ public class GradleExecutionHelper {
}
@NotNull
private static String getToolingExtensionsJarPaths() throws ClassNotFoundException {
final ArrayList<Class<?>> list = ContainerUtil.newArrayList(
// add gradle-tooling-extension-api jar
Class.forName("org.jetbrains.plugins.gradle.model.ProjectImportAction"),
// add gradle-tooling-extension-impl jar
Class.forName("org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl")
);
private static String getToolingExtensionsJarPaths(@NotNull Set<Class> toolingExtensionClasses) {
StringBuilder buf = new StringBuilder();
buf.append('[');
for (Iterator<Class<?>> it = list.iterator(); it.hasNext(); ) {
for (Iterator<Class> it = toolingExtensionClasses.iterator(); it.hasNext(); ) {
Class<?> aClass = it.next();
String jarPath = PathUtil.getCanonicalPath(PathUtil.getJarPathForClass(aClass));
buf.append('\"').append(jarPath).append('\"');
@@ -87,33 +87,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
@Nullable final GradleExecutionSettings settings,
@NotNull final ExternalSystemTaskNotificationListener listener)
throws ExternalSystemException, IllegalArgumentException, IllegalStateException {
final GradleProjectResolverExtension projectResolverChain;
if (settings != null) {
myHelper.ensureInstalledWrapper(id, projectPath, settings, listener);
List<ClassHolder<? extends GradleProjectResolverExtension>> extensionClasses = settings.getResolverExtensions();
Deque<GradleProjectResolverExtension> extensions = new ArrayDeque<GradleProjectResolverExtension>();
for (ClassHolder<? extends GradleProjectResolverExtension> holder : extensionClasses) {
final GradleProjectResolverExtension extension;
try {
extension = holder.getTargetClass().newInstance();
}
catch (Throwable e) {
throw new IllegalArgumentException(
String.format("Can't instantiate project resolve extension for class '%s'", holder.getTargetClassName()), e);
}
final GradleProjectResolverExtension previous = extensions.peekLast();
if (previous != null) {
previous.setNext(extension);
}
extensions.add(extension);
}
projectResolverChain = extensions.peekFirst();
}
else {
projectResolverChain = new BaseGradleProjectResolverExtension();
}
final GradleProjectResolverExtension projectResolverChain = createProjectResolverChain(settings);
final DataNode<ProjectData> resultProjectDataNode = myHelper.execute(
projectPath, settings,
new ProjectConnectionDataNodeFunction(
@@ -145,6 +123,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
final List<KeyValue<String, String>> extraJvmArgs = new ArrayList<KeyValue<String, String>>();
final List<String> commandLineArgs = ContainerUtil.newArrayList();
final Set<Class> toolingExtensionClasses = ContainerUtil.newHashSet();
for (GradleProjectResolverExtension resolverExtension = projectResolverChain;
resolverExtension != null;
@@ -159,6 +138,8 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
extraJvmArgs.addAll(resolverExtension.getExtraJvmArgs());
// collect extra command-line arguments
commandLineArgs.addAll(resolverExtension.getExtraCommandLineArgs());
// collect tooling extensions classes
toolingExtensionClasses.addAll(resolverExtension.getToolingExtensionsClasses());
}
final ParametersList parametersList = new ParametersList();
@@ -171,7 +152,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
// TODO [vlad] remove the check
if (!GradleEnvironment.DISABLE_ENHANCED_TOOLING_API) {
File initScript = GradleExecutionHelper.generateInitScript(isBuildSrcProject);
File initScript = GradleExecutionHelper.generateInitScript(isBuildSrcProject, toolingExtensionClasses);
if (initScript != null) {
ContainerUtil.addAll(commandLineArgs, GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
}
@@ -260,7 +241,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
projectResolverChain.populateModuleContentRoots(ideaModule, moduleDataNode);
projectResolverChain.populateModuleCompileOutputSettings(ideaModule, moduleDataNode);
projectResolverChain.populateModuleDependencies(ideaModule, moduleDataNode, projectDataNode);
if(!isBuildSrcProject) {
if (!isBuildSrcProject) {
final Collection<TaskData> moduleTasks = projectResolverChain.populateModuleTasks(ideaModule, moduleDataNode, projectDataNode);
allTasks.addAll(moduleTasks);
}
@@ -299,8 +280,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
private void handleBuildSrcProject(@NotNull final DataNode<ProjectData> resultProjectDataNode,
@NotNull final ProjectConnectionDataNodeFunction projectConnectionDataNodeFunction) {
if (projectConnectionDataNodeFunction.myIsPreviewMode || GradleEnvironment.DISABLE_ENHANCED_TOOLING_API ||
!new File(projectConnectionDataNodeFunction.myProjectPath).isDirectory()) return;
if (projectConnectionDataNodeFunction.myIsPreviewMode
|| GradleEnvironment.DISABLE_ENHANCED_TOOLING_API
|| !new File(projectConnectionDataNodeFunction.myProjectPath).isDirectory()) {
return;
}
final DataNode<ModuleData> buildSrcModuleDataNode =
ExternalSystemApiUtil.find(resultProjectDataNode, ProjectKeys.MODULE, new BooleanFunction<DataNode<ModuleData>>() {
@@ -369,4 +353,48 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
}
}
}
@NotNull
public static GradleProjectResolverExtension createProjectResolverChain(@Nullable final GradleExecutionSettings settings) {
final GradleProjectResolverExtension projectResolverChain;
if (settings != null) {
List<ClassHolder<? extends GradleProjectResolverExtension>> extensionClasses = settings.getResolverExtensions();
Deque<GradleProjectResolverExtension> extensions = new ArrayDeque<GradleProjectResolverExtension>();
for (ClassHolder<? extends GradleProjectResolverExtension> holder : extensionClasses) {
final GradleProjectResolverExtension extension;
try {
extension = holder.getTargetClass().newInstance();
}
catch (Throwable e) {
throw new IllegalArgumentException(
String.format("Can't instantiate project resolve extension for class '%s'", holder.getTargetClassName()), e);
}
final GradleProjectResolverExtension previous = extensions.peekLast();
if (previous != null) {
previous.setNext(extension);
if (previous.getNext() != extension) {
throw new AssertionError("Illegal next resolver got, current resolver class is " + previous.getClass().getName());
}
}
extensions.add(extension);
}
projectResolverChain = extensions.peekFirst();
GradleProjectResolverExtension resolverExtension = projectResolverChain;
assert resolverExtension != null;
while (resolverExtension.getNext() != null) {
resolverExtension = resolverExtension.getNext();
}
if (!(resolverExtension instanceof BaseGradleProjectResolverExtension)) {
throw new AssertionError("Illegal last resolver got of class " + resolverExtension.getClass().getName());
}
}
else {
projectResolverChain = new BaseGradleProjectResolverExtension();
}
return projectResolverChain;
}
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.service.ParametersEnhancer;
import com.intellij.openapi.util.KeyValue;
import com.intellij.util.Consumer;
import org.gradle.tooling.model.idea.IdeaModule;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -50,7 +51,7 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
void setProjectResolverContext(@NotNull ProjectResolverContext projectResolverContext);
void setNext(@Nullable GradleProjectResolverExtension projectResolverExtension);
void setNext(@NotNull GradleProjectResolverExtension projectResolverExtension);
@Nullable
GradleProjectResolverExtension getNext();
@@ -98,6 +99,14 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
@NotNull
Set<Class> getExtraProjectModelClasses();
/**
* add paths containing these classes to classpath of gradle tooling extension
*
* @return classes to be available for gradle
*/
@NotNull
Set<Class> getToolingExtensionsClasses();
@NotNull
List<KeyValue<String, String>> getExtraJvmArgs();
@@ -111,4 +120,6 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
* Performs project configuration and other checks before the actual project import (before invocation of gradle tooling API).
*/
void preImportCheck();
void enhanceTaskProcessing(@NotNull List<String> taskNames, @Nullable String debuggerSetup, @NotNull Consumer<String> initScriptConsumer);
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
@@ -33,6 +34,8 @@ import org.gradle.tooling.ProjectConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper;
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver;
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension;
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
import org.jetbrains.plugins.gradle.util.GradleConstants;
@@ -75,18 +78,32 @@ public class GradleTaskManager extends AbstractExternalSystemTaskManager<GradleE
Function<ProjectConnection, Void> f = new Function<ProjectConnection, Void>() {
@Override
public Void fun(ProjectConnection connection) {
if (!StringUtil.isEmpty(debuggerSetup)) {
final List<String> initScripts = ContainerUtil.newArrayList();
final GradleProjectResolverExtension projectResolverChain = GradleProjectResolver.createProjectResolverChain(settings);
for (GradleProjectResolverExtension resolverExtension = projectResolverChain;
resolverExtension != null;
resolverExtension = resolverExtension.getNext()) {
final String resolverClassName = resolverExtension.getClass().getName();
resolverExtension.enhanceTaskProcessing(taskNames, debuggerSetup, new Consumer<String>() {
@Override
public void consume(String script) {
if (StringUtil.isNotEmpty(script)) {
ContainerUtil.addAllNotNull(
initScripts,
"//-- Generated by " + resolverClassName,
script,
"//");
}
}
});
}
if (!initScripts.isEmpty()) {
try {
final File tempFile = FileUtil.createTempFile("init", ".gradle");
tempFile.deleteOnExit();
final String[] lines = {
"gradle.taskGraph.beforeTask { Task task ->",
" if (task instanceof JavaForkOptions) {",
" task.jvmArgs '" + debuggerSetup.trim() + '\'',
"}}",
};
FileUtil.writeToFile(tempFile, StringUtil.join(lines, SystemProperties.getLineSeparator()));
FileUtil.writeToFile(tempFile, StringUtil.join(initScripts, SystemProperties.getLineSeparator()));
ContainerUtil.addAll(scriptParameters, GradleConstants.INIT_SCRIPT_CMD_OPTION, tempFile.getAbsolutePath());
}
catch (IOException e) {
@@ -11,7 +11,7 @@
<orderEntry type="module" module-name="annotations" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="module-library">
<orderEntry type="module-library" exported="">
<library name="Gradle">
<CLASSES>
<root url="jar://$MODULE_DIR$/../lib/gradle-tooling-api-1.12.jar!/" />
@@ -18,11 +18,13 @@ package org.jetbrains.plugins.gradle.tooling;
import org.gradle.api.Project;
import org.jetbrains.annotations.NotNull;
import java.io.Serializable;
/**
* @author Vladislav.Soroka
* @since 11/5/13
*/
public interface ModelBuilderService {
public interface ModelBuilderService extends Serializable {
boolean canBuild(String modelName);
Object buildAll(String modelName, Project project);
@@ -15,16 +15,23 @@
*/
package org.jetbrains.plugins.gradle.tooling.builder;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.util.Function;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.gradle.tooling.BuildActionExecuter;
import org.gradle.tooling.GradleConnector;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
import org.gradle.tooling.model.DomainObjectSet;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.util.GradleVersion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel;
import org.jetbrains.plugins.gradle.model.ClasspathEntryModel;
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper;
import org.jetbrains.plugins.gradle.util.GradleConstants;
@@ -39,13 +46,12 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
@@ -58,7 +64,7 @@ public abstract class AbstractModelBuilderTest {
public static final String GRADLE_v1_9 = "1.9";
public static final String GRADLE_v1_10 = "1.10";
public static final String GRADLE_v1_11 = "1.11";
public static final String GRADLE_v1_12 = "1.12-rc-1";
public static final String GRADLE_v1_12 = "1.12";
public static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*)\\]");
@@ -136,13 +142,31 @@ public abstract class AbstractModelBuilderTest {
final ProjectImportAction projectImportAction = new ProjectImportAction(false);
projectImportAction.addExtraProjectModelClasses(getModels());
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
File initScript = GradleExecutionHelper.generateInitScript(false);
File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
assertNotNull(initScript);
buildActionExecutor.withArguments(GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
allModels = buildActionExecutor.run();
assertNotNull(allModels);
}
@NotNull
private Set<Class> getToolingExtensionClasses() {
final Set<Class> classes = ContainerUtil.<Class>set(
// gradle-tooling-extension-api jar
ProjectImportAction.class,
// gradle-tooling-extension-impl jar
ModelBuildScriptClasspathBuilderImpl.class
);
ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
return classes;
}
@NotNull
protected Set<Class> doGetToolingExtensionClasses() {
return Collections.emptySet();
}
@After
public void tearDown() throws Exception {
if (testDir != null) {
@@ -152,6 +176,43 @@ public abstract class AbstractModelBuilderTest {
protected abstract Set<Class> getModels();
protected <T> Map<String, T> getModulesMap(final Class<T> aClass) {
final DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
final String filterKey = "to_filter";
final Map<String, T> map = ContainerUtil.map2Map(ideaModules, new Function<IdeaModule, Pair<String, T>>() {
@Override
public Pair<String, T> fun(IdeaModule module) {
final T value = allModels.getExtraProject(module, aClass);
final String key = value != null ? module.getGradleProject().getPath() : filterKey;
return Pair.create(key, value);
}
});
map.remove(filterKey);
return map;
}
protected void assertBuildClasspath(String projectPath, String... classpath) {
final Map<String, BuildScriptClasspathModel> classpathModelMap = getModulesMap(BuildScriptClasspathModel.class);
final BuildScriptClasspathModel classpathModel = classpathModelMap.get(projectPath);
assertNotNull(classpathModel);
final List<? extends ClasspathEntryModel> classpathEntryModels = classpathModel.getClasspath().getAll();
assertEquals(classpath.length, classpathEntryModels.size());
for (int i = 0, length = classpath.length; i < length; i++) {
String classpathEntry = classpath[i];
final ClasspathEntryModel classpathEntryModel = classpathEntryModels.get(i);
assertNotNull(classpathEntryModel);
assertEquals(1, classpathEntryModel.getClasses().size());
final String path = classpathEntryModel.getClasses().iterator().next();
assertEquals(classpathEntry, new File(path).getName());
}
}
private static void ensureTempDirCreated() throws IOException {
if (ourTempDir != null) return;
+1
View File
@@ -36,6 +36,7 @@
<orderEntry type="module" module-name="ByteCodeViewer" />
<orderEntry type="module" module-name="properties-psi-api" />
<orderEntry type="module" module-name="groovy-psi" exported="" />
<orderEntry type="module" module-name="external-system-api" />
</component>
</module>
+1
View File
@@ -69,6 +69,7 @@
<extensionPoint name="groovySourceFolderDetector" interface="org.jetbrains.plugins.groovy.actions.GroovySourceFolderDetector"/>
<extensionPoint name="mvc.framework" interface="org.jetbrains.plugins.groovy.mvc.MvcFramework"/>
<extensionPoint name="mvc.command.executor" interface="org.jetbrains.plugins.groovy.mvc.MvcCommandExecutor"/>
<extensionPoint name="closureCompleter" interface="org.jetbrains.plugins.groovy.lang.completion.ClosureCompleter"/>
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.mvc;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Vladislav.Soroka
* @since 6/19/2014
*/
public class MvcCliCommandExecutor extends MvcCommandExecutor {
@Override
protected boolean isApplicable(Module module) {
return true;
}
@Nullable
@Override
protected ConsoleProcessDescriptor doRun(@NotNull Module module,
@NotNull MvcFramework framework,
@NotNull MvcCommand mvcCommand,
@Nullable Runnable onDone,
boolean showConsole,
boolean closeOnDone,
String... input) {
final GeneralCommandLine commandLine = framework.createCommandAndShowErrors(null, module, mvcCommand);
if (commandLine == null) return null;
return MvcConsole.executeProcess(module, commandLine, onDone, closeOnDone, input);
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.mvc;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Vladislav.Soroka
* @since 6/19/2014
*/
public abstract class MvcCommandExecutor {
private static final ExtensionPointName<MvcCommandExecutor> EP_NAME =
ExtensionPointName.create("org.intellij.groovy.mvc.command.executor");
@Nullable
public static ConsoleProcessDescriptor run(@NotNull Module module,
@NotNull MvcFramework framework,
@NotNull MvcCommand mvcCommand,
@Nullable Runnable onDone,
boolean closeOnDone,
String... input) {
return run(module, framework, mvcCommand, onDone, true, closeOnDone, input);
}
@Nullable
public static ConsoleProcessDescriptor run(@NotNull Module module,
@NotNull MvcFramework framework,
@NotNull MvcCommand mvcCommand,
@Nullable Runnable onDone,
boolean showConsole,
boolean closeOnDone,
String... input) {
for (MvcCommandExecutor executor : EP_NAME.getExtensions()) {
if (executor.isApplicable(module)) {
return executor.doRun(module, framework, mvcCommand, onDone, showConsole, closeOnDone, input);
}
}
// fallback to default CLI implementation
return new MvcCliCommandExecutor().doRun(module, framework, mvcCommand, onDone, showConsole, closeOnDone, input);
}
protected abstract boolean isApplicable(Module module);
@Nullable
protected abstract ConsoleProcessDescriptor doRun(@NotNull Module module,
@NotNull MvcFramework framework,
@NotNull MvcCommand mvcCommand,
@Nullable Runnable onDone,
boolean showConsole,
boolean closeOnDone,
String... input);
}
@@ -15,7 +15,6 @@
*/
package org.jetbrains.plugins.groovy.mvc;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
@@ -34,13 +33,8 @@ public class MvcRunTarget extends MvcActionBase {
}
Module selectedModule = dialog.getSelectedModule();
MvcCommand cmd = MvcCommand.parse(dialog.getTargetArguments());
final GeneralCommandLine commandLine = framework.createCommandAndShowErrors(dialog.getVmOptions(), selectedModule, cmd);
if (commandLine == null) return;
MvcConsole.executeProcess(selectedModule, commandLine, null, false);
MvcCommandExecutor.run(selectedModule, framework, cmd, null, false);
}
}