summaryrefslogtreecommitdiff
path: root/plugins/gradle/src/org/jetbrains
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gradle/src/org/jetbrains')
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/compiler/GradleBuildProcessParametersProvider.java93
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleResourceCompilerConfigurationGenerator.java186
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/execution/GradleOrderEnumeratorHandler.java112
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java6
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java83
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java3
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java3
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java22
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectResolverContext.java8
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectDataService.java233
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java262
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectOpenProcessor.java97
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java5
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java12
14 files changed, 1099 insertions, 26 deletions
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/compiler/GradleBuildProcessParametersProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/compiler/GradleBuildProcessParametersProvider.java
new file mode 100644
index 000000000000..4337686235f5
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/compiler/GradleBuildProcessParametersProvider.java
@@ -0,0 +1,93 @@
+/*
+ * 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.gradle.compiler;
+
+import com.google.gson.Gson;
+import com.intellij.compiler.server.BuildProcessParametersProvider;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.PathUtil;
+import com.intellij.util.containers.ContainerUtil;
+import groovy.lang.GroovyObject;
+import org.apache.tools.ant.taskdefs.Ant;
+import org.gradle.tooling.ProjectConnection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Adds Gradle build dependencies to the project build process' classpath.
+ *
+ * @author Vladislav.Soroka
+ * @since 7/22/2014
+ */
+public class GradleBuildProcessParametersProvider extends BuildProcessParametersProvider {
+ @NotNull private final Project myProject;
+
+ private List<String> myClasspath;
+
+ public GradleBuildProcessParametersProvider(@NotNull Project project) {
+ myProject = project;
+ }
+
+ @Override
+ @NotNull
+ public List<String> getClassPath() {
+ if (myClasspath == null) {
+ myClasspath = ContainerUtil.newArrayList();
+ addGradleClassPath(myClasspath);
+ final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
+ for (Module module : moduleManager.getModules()) {
+ if (ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) {
+ addOtherClassPath(myClasspath);
+ break;
+ }
+ }
+ }
+ return myClasspath;
+ }
+
+ private static void addGradleClassPath(@NotNull final List<String> classpath) {
+ String gradleLibDirPath = null;
+ String gradleToolingApiJarPath = PathUtil.getJarPathForClass(ProjectConnection.class);
+ if (!StringUtil.isEmpty(gradleToolingApiJarPath)) {
+ gradleLibDirPath = PathUtil.getParentPath(gradleToolingApiJarPath);
+ }
+ if (gradleLibDirPath == null || gradleLibDirPath.isEmpty()) return;
+
+ File gradleLibDir = new File(gradleLibDirPath);
+ if (!gradleLibDir.isDirectory()) return;
+
+ File[] children = FileUtil.notNullize(gradleLibDir.listFiles());
+ for (File child : children) {
+ if (child.isFile() && child.getName().endsWith(".jar")) {
+ classpath.add(child.getAbsolutePath());
+ }
+ }
+ }
+
+ private static void addOtherClassPath(@NotNull final List<String> classpath) {
+ classpath.add(PathUtil.getJarPathForClass(Ant.class));
+ classpath.add(PathUtil.getJarPathForClass(GroovyObject.class));
+ classpath.add(PathUtil.getJarPathForClass(Gson.class));
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleResourceCompilerConfigurationGenerator.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleResourceCompilerConfigurationGenerator.java
new file mode 100644
index 000000000000..01c5275f3828
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleResourceCompilerConfigurationGenerator.java
@@ -0,0 +1,186 @@
+/*
+ * 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.gradle.config;
+
+import com.intellij.compiler.server.BuildManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.model.ExternalFilter;
+import com.intellij.openapi.externalSystem.model.ExternalProject;
+import com.intellij.openapi.externalSystem.model.ExternalSourceDirectorySet;
+import com.intellij.openapi.externalSystem.model.ExternalSourceSet;
+import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
+import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.util.containers.FactoryMap;
+import com.intellij.util.xmlb.XmlSerializer;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.gradle.model.impl.*;
+import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataService;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/10/2014
+ */
+public class GradleResourceCompilerConfigurationGenerator {
+
+ private static Logger LOG = Logger.getInstance(GradleResourceCompilerConfigurationGenerator.class);
+
+ @NotNull private final Project myProject;
+ @NotNull private final CompileContext myContext;
+ @NotNull private final Map<String, ExternalProject> myExternalProjectMap;
+ private final ExternalProjectDataService myExternalProjectDataService;
+
+ public GradleResourceCompilerConfigurationGenerator(@NotNull final Project project, @NotNull final CompileContext context) {
+ myProject = project;
+ myContext = context;
+ myExternalProjectDataService =
+ (ExternalProjectDataService)ServiceManager.getService(ProjectDataManager.class).getDataService(ExternalProjectDataService.KEY);
+ assert myExternalProjectDataService != null;
+
+ myExternalProjectMap = new FactoryMap<String, ExternalProject>() {
+ @Nullable
+ @Override
+ protected ExternalProject create(String gradleProjectPath) {
+ return myExternalProjectDataService.getOrImportRootExternalProject(project, GradleConstants.SYSTEM_ID, new File(gradleProjectPath));
+ }
+ };
+ }
+
+ public void generateBuildConfiguration() {
+ if (!hasGradleModules()) return;
+
+ final BuildManager buildManager = BuildManager.getInstance();
+ final File projectSystemDir = buildManager.getProjectSystemDirectory(myProject);
+ if (projectSystemDir == null) return;
+
+ final File gradleConfigFile = new File(projectSystemDir, GradleProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH);
+
+ GradleProjectConfiguration projectConfig = new GradleProjectConfiguration();
+ for (Module module : myContext.getCompileScope().getAffectedModules()) {
+ if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) continue;
+
+ final String gradleProjectPath = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
+ assert gradleProjectPath != null;
+ final ExternalProject externalRootProject = myExternalProjectMap.get(gradleProjectPath);
+ if (externalRootProject == null) {
+ myContext.addMessage(CompilerMessageCategory.ERROR,
+ String.format("Unable to make the module: %s, related gradle module configuration was not imported",
+ module.getName()),
+ VfsUtilCore.pathToUrl(gradleProjectPath), -1, -1);
+ continue;
+ }
+
+ ExternalProject externalProject = myExternalProjectDataService.findExternalProject(externalRootProject, module);
+ if (externalProject == null) {
+ LOG.warn("Unable to find config for module: " + module.getName());
+ continue;
+ }
+
+ final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
+ assert compilerModuleExtension != null;
+
+ GradleModuleResourceConfiguration resourceConfig = new GradleModuleResourceConfiguration();
+ resourceConfig.id = new ModuleVersion(externalProject.getGroup(), externalProject.getName(), externalProject.getVersion());
+ resourceConfig.directory = FileUtil.toSystemIndependentName(externalProject.getProjectDir().getPath());
+
+ final ExternalSourceSet mainSourcesSet = externalProject.getSourceSets().get("main");
+ addResources(resourceConfig.resources, mainSourcesSet, ExternalSystemSourceType.RESOURCE);
+
+ final ExternalSourceSet testSourcesSet = externalProject.getSourceSets().get("test");
+ addResources(resourceConfig.testResources, testSourcesSet, ExternalSystemSourceType.TEST_RESOURCE);
+
+ projectConfig.moduleConfigurations.put(module.getName(), resourceConfig);
+ }
+
+ final Document document = new Document(new Element("gradle-project-configuration"));
+ XmlSerializer.serializeInto(projectConfig, document.getRootElement());
+ buildManager.runCommand(new Runnable() {
+ @Override
+ public void run() {
+ buildManager.clearState(myProject);
+ FileUtil.createIfDoesntExist(gradleConfigFile);
+ try {
+ JDOMUtil.writeDocument(document, gradleConfigFile, "\n");
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+
+ private boolean hasGradleModules() {
+ for (Module module : myContext.getCompileScope().getAffectedModules()) {
+ if (ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return true;
+ }
+ return false;
+ }
+
+ private static void addResources(@NotNull List<ResourceRootConfiguration> container,
+ @Nullable ExternalSourceSet externalSourceSet,
+ @NotNull ExternalSystemSourceType sourceType) {
+ if (externalSourceSet == null) return;
+ final ExternalSourceDirectorySet directorySet = externalSourceSet.getSources().get(sourceType);
+ if (directorySet == null) return;
+
+ for (File file : directorySet.getSrcDirs()) {
+ final String dir = file.getPath();
+ final ResourceRootConfiguration rootConfiguration = new ResourceRootConfiguration();
+ rootConfiguration.directory = FileUtil.toSystemIndependentName(dir);
+ final String target = directorySet.getOutputDir().getPath();
+ rootConfiguration.targetPath = FileUtil.toSystemIndependentName(target);
+
+ rootConfiguration.includes.clear();
+ for (String include : directorySet.getIncludes()) {
+ rootConfiguration.includes.add(include.trim());
+ }
+ rootConfiguration.excludes.clear();
+ for (String exclude : directorySet.getExcludes()) {
+ rootConfiguration.excludes.add(exclude.trim());
+ }
+
+ rootConfiguration.isFiltered = !directorySet.getFilters().isEmpty();
+ rootConfiguration.filters.clear();
+ for (ExternalFilter filter : directorySet.getFilters()) {
+ final ResourceRootFilter resourceRootFilter = new ResourceRootFilter();
+ resourceRootFilter.filterType = filter.getFilterType();
+ resourceRootFilter.properties = filter.getPropertiesAsJsonMap();
+ rootConfiguration.filters.add(resourceRootFilter);
+ }
+
+ container.add(rootConfiguration);
+ }
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/GradleOrderEnumeratorHandler.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/GradleOrderEnumeratorHandler.java
new file mode 100644
index 000000000000..113e49a61a25
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/GradleOrderEnumeratorHandler.java
@@ -0,0 +1,112 @@
+/*
+ * 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.gradle.execution;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.model.ExternalProject;
+import com.intellij.openapi.externalSystem.model.ExternalSourceDirectorySet;
+import com.intellij.openapi.externalSystem.model.ExternalSourceSet;
+import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
+import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModuleRootModel;
+import com.intellij.openapi.roots.OrderEnumerationHandler;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataService;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+
+import java.io.File;
+import java.util.Collection;
+
+public class GradleOrderEnumeratorHandler extends OrderEnumerationHandler {
+ private static final Logger LOG = Logger.getInstance(GradleOrderEnumeratorHandler.class);
+
+ public static class FactoryImpl extends Factory {
+ @Override
+ public boolean isApplicable(@NotNull Project project) {
+ return true;
+ }
+
+ @Override
+ public boolean isApplicable(@NotNull Module module) {
+ return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module);
+ }
+
+ @Override
+ public OrderEnumerationHandler createHandler(@Nullable Module module) {
+ return INSTANCE;
+ }
+ }
+
+ private static final GradleOrderEnumeratorHandler INSTANCE = new GradleOrderEnumeratorHandler();
+
+ @Override
+ public boolean addCustomModuleRoots(@NotNull OrderRootType type,
+ @NotNull ModuleRootModel rootModel,
+ @NotNull Collection<String> result,
+ boolean includeProduction,
+ boolean includeTests) {
+ if (!type.equals(OrderRootType.CLASSES)) return false;
+ if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.getModule())) return false;
+
+ final String gradleProjectPath = rootModel.getModule().getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
+ if (gradleProjectPath == null) {
+ LOG.error("Root project path of the Gradle project not found for " + rootModel.getModule());
+ return false;
+ }
+
+ final ExternalProjectDataService externalProjectDataService =
+ (ExternalProjectDataService)ServiceManager.getService(ProjectDataManager.class).getDataService(ExternalProjectDataService.KEY);
+
+ assert externalProjectDataService != null;
+ final ExternalProject externalRootProject =
+ externalProjectDataService.getRootExternalProject(GradleConstants.SYSTEM_ID, new File(gradleProjectPath));
+ if (externalRootProject == null) {
+ LOG.debug("Root external project was not yep imported for the project path: " + gradleProjectPath);
+ return false;
+ }
+
+ ExternalProject externalProject = externalProjectDataService.findExternalProject(externalRootProject, rootModel.getModule());
+ if (externalProject == null) return false;
+
+ if (includeProduction) {
+ addOutputRoots(externalProject.getSourceSets().get("main"), ExternalSystemSourceType.RESOURCE, result);
+ }
+
+ if (includeTests) {
+ addOutputRoots(externalProject.getSourceSets().get("test"), ExternalSystemSourceType.TEST_RESOURCE, result);
+ }
+
+ return true;
+ }
+
+ private static void addOutputRoots(@Nullable ExternalSourceSet externalSourceSet,
+ @NotNull ExternalSystemSourceType sourceType,
+ @NotNull Collection<String> result) {
+ if (externalSourceSet == null) return;
+ final ExternalSourceDirectorySet directorySet = externalSourceSet.getSources().get(sourceType);
+ if (directorySet == null) return;
+
+ result.add(VfsUtilCore.pathToUrl(directorySet.getOutputDir().getAbsolutePath()));
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
index 1d8addd31369..9603470a0878 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
@@ -28,6 +28,7 @@ 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.gradle.tooling.model.idea.IdeaProject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -80,6 +81,11 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
return nextResolver.createJavaProjectData();
}
+ @Override
+ public void populateProjectExtraModels(@NotNull IdeaProject gradleProject, @NotNull DataNode<ProjectData> ideProject) {
+ nextResolver.populateProjectExtraModels(gradleProject, ideProject);
+ }
+
@NotNull
@Override
public ModuleData createModule(@NotNull IdeaModule gradleModule, @NotNull ProjectData projectData) {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
index 6f43559f7a11..ad7ade6a3c58 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
@@ -15,14 +15,13 @@
*/
package org.jetbrains.plugins.gradle.service.project;
+import com.google.gson.GsonBuilder;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.externalSystem.JavaProjectData;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.externalSystem.model.DataNode;
-import com.intellij.openapi.externalSystem.model.ExternalSystemException;
-import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.*;
import com.intellij.openapi.externalSystem.model.project.*;
import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
@@ -56,6 +55,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.service.project.data.ExternalProjectDataService;
import org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl;
import org.jetbrains.plugins.gradle.tooling.internal.init.Init;
import org.jetbrains.plugins.gradle.util.GradleBundle;
@@ -79,6 +79,8 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
private static final Logger LOG = Logger.getInstance("#" + BaseGradleProjectResolverExtension.class.getName());
@NotNull @NonNls private static final String UNRESOLVED_DEPENDENCY_PREFIX = "unresolved dependency - ";
+ private static final String MAIN_SOURCE_SET = "main";
+ private static final String TEST_SOURCE_SET = "test";
@NotNull private ProjectResolverContext resolverCtx;
@NotNull private final BaseProjectImportErrorHandler myErrorHandler = new BaseProjectImportErrorHandler();
@@ -120,6 +122,14 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
return javaProjectData;
}
+ @Override
+ public void populateProjectExtraModels(@NotNull IdeaProject gradleProject, @NotNull DataNode<ProjectData> ideProject) {
+ final ExternalProject externalProject = resolverCtx.getExtraProject(ExternalProject.class);
+ if (externalProject != null) {
+ ideProject.createChild(ExternalProjectDataService.KEY, externalProject);
+ }
+ }
+
@NotNull
@Override
public ModuleData createModule(@NotNull IdeaModule gradleModule, @NotNull ProjectData projectData) {
@@ -220,6 +230,8 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
File sourceCompileOutputPath = null;
File testCompileOutputPath = null;
+ File resourceCompileOutputPath;
+ File testResourceCompileOutputPath;
boolean inheritOutputDirs = false;
ModuleData moduleData = ideModule.getData();
@@ -229,30 +241,71 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
inheritOutputDirs = moduleCompilerOutput.getInheritOutputDirs();
}
+ ExternalProject externalProject = resolverCtx.getExtraProject(gradleModule, ExternalProject.class);
+ if (externalProject != null) {
+ externalProject = new DefaultExternalProject(externalProject);
+ }
+
if (!inheritOutputDirs && (sourceCompileOutputPath == null || testCompileOutputPath == null)) {
- ModuleExtendedModel moduleExtendedModel = resolverCtx.getExtraProject(gradleModule, ModuleExtendedModel.class);
- if (moduleExtendedModel != null) {
- ExtIdeaCompilerOutput output = moduleExtendedModel.getCompilerOutput();
- if (output != null) {
- if (sourceCompileOutputPath == null) {
- sourceCompileOutputPath = output.getMainClassesDir();
+ sourceCompileOutputPath = getCompileOutputPath(externalProject, MAIN_SOURCE_SET, ExternalSystemSourceType.SOURCE);
+ resourceCompileOutputPath = getCompileOutputPath(externalProject, MAIN_SOURCE_SET, ExternalSystemSourceType.RESOURCE);
+ testCompileOutputPath = getCompileOutputPath(externalProject, TEST_SOURCE_SET, ExternalSystemSourceType.TEST);
+ testResourceCompileOutputPath = getCompileOutputPath(externalProject, TEST_SOURCE_SET, ExternalSystemSourceType.TEST_RESOURCE);
+ }
+ else {
+ resourceCompileOutputPath = sourceCompileOutputPath;
+ testResourceCompileOutputPath = testCompileOutputPath;
+
+ if (externalProject != null) {
+ final ExternalSourceSet mainSourceSet = externalProject.getSourceSets().get(MAIN_SOURCE_SET);
+ if (mainSourceSet != null) {
+ final ExternalSourceDirectorySet resourceDirectories = mainSourceSet.getSources().get(ExternalSystemSourceType.RESOURCE);
+ if (resourceDirectories instanceof DefaultExternalSourceDirectorySet) {
+ ((DefaultExternalSourceDirectorySet)resourceDirectories).setOutputDir(sourceCompileOutputPath);
}
- if (testCompileOutputPath == null) {
- testCompileOutputPath = output.getTestClassesDir();
+ }
+ final ExternalSourceSet testSourceSet = externalProject.getSourceSets().get(TEST_SOURCE_SET);
+ if (testSourceSet != null) {
+ final ExternalSourceDirectorySet testResourceDirectories = testSourceSet.getSources().get(ExternalSystemSourceType.TEST_RESOURCE);
+ if (testResourceDirectories instanceof DefaultExternalSourceDirectorySet) {
+ ((DefaultExternalSourceDirectorySet)testResourceDirectories).setOutputDir(testCompileOutputPath);
}
}
+
+ final DataNode<ProjectData> projectDataNode = ExternalSystemApiUtil.findParent(ideModule, ProjectKeys.PROJECT);
+ assert projectDataNode != null;
+ projectDataNode.createOrReplaceChild(ExternalProjectDataService.KEY, externalProject);
}
}
if (sourceCompileOutputPath != null) {
moduleData.setCompileOutputPath(ExternalSystemSourceType.SOURCE, sourceCompileOutputPath.getAbsolutePath());
}
+ if (resourceCompileOutputPath != null) {
+ moduleData.setCompileOutputPath(ExternalSystemSourceType.RESOURCE, resourceCompileOutputPath.getAbsolutePath());
+ }
if (testCompileOutputPath != null) {
moduleData.setCompileOutputPath(ExternalSystemSourceType.TEST, testCompileOutputPath.getAbsolutePath());
}
+ if (testResourceCompileOutputPath != null) {
+ moduleData.setCompileOutputPath(ExternalSystemSourceType.TEST_RESOURCE, testResourceCompileOutputPath.getAbsolutePath());
+ }
+
moduleData.setInheritProjectCompileOutputPath(inheritOutputDirs || sourceCompileOutputPath == null);
}
+ @Nullable
+ private static File getCompileOutputPath(@Nullable ExternalProject externalProject,
+ @NotNull String sourceSetName,
+ @NotNull ExternalSystemSourceType sourceType) {
+ if (externalProject == null) return null;
+ final ExternalSourceSet sourceSet = externalProject.getSourceSets().get(sourceSetName);
+ if(sourceSet == null) return null;
+
+ final ExternalSourceDirectorySet directorySet = sourceSet.getSources().get(sourceType);
+ return directorySet != null ? directorySet.getOutputDir() : null;
+ }
+
@Override
public void populateModuleDependencies(@NotNull IdeaModule gradleModule,
@NotNull DataNode<ModuleData> ideModule,
@@ -319,17 +372,19 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
@Override
public Set<Class> getExtraProjectModelClasses() {
return ContainerUtil.<Class>set(
- GradleBuild.class, ModuleExtendedModel.class, BuildScriptClasspathModel.class);
+ GradleBuild.class, ExternalProject.class, ModuleExtendedModel.class, BuildScriptClasspathModel.class);
}
@NotNull
@Override
public Set<Class> getToolingExtensionsClasses() {
return ContainerUtil.<Class>set(
+ ExternalProject.class,
// gradle-tooling-extension-api jar
ProjectImportAction.class,
// gradle-tooling-extension-impl jar
- ModelBuildScriptClasspathBuilderImpl.class
+ ModelBuildScriptClasspathBuilderImpl.class,
+ GsonBuilder.class
);
}
@@ -416,6 +471,8 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
List<String> additionalEntries = ContainerUtilRt.newArrayList();
ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(GroovyObject.class));
+ ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(GsonBuilder.class));
+ ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(ExternalProject.class));
ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(JavaProjectData.class));
ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(LanguageLevel.class));
ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(StdModuleTypes.class));
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
index 8a2ffaae36c9..24c8e126ed3f 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
@@ -199,6 +199,9 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
projectDataNode.createChild(JavaProjectData.KEY, javaProjectData);
IdeaProject ideaProject = resolverCtx.getModels().getIdeaProject();
+
+ projectResolverChain.populateProjectExtraModels(ideaProject, projectDataNode);
+
DomainObjectSet<? extends IdeaModule> gradleModules = ideaProject.getModules();
if (gradleModules == null || gradleModules.isEmpty()) {
throw new IllegalStateException("No modules found for the target project: " + ideaProject);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
index b727005db845..6dd201b839fb 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
@@ -27,6 +27,7 @@ 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.gradle.tooling.model.idea.IdeaProject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.GradleManager;
@@ -62,6 +63,8 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
@NotNull
JavaProjectData createJavaProjectData();
+ void populateProjectExtraModels(@NotNull IdeaProject gradleProject, @NotNull DataNode<ProjectData> ideProject);
+
@NotNull
ModuleData createModule(@NotNull IdeaModule gradleModule, @NotNull ProjectData projectData);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
index 81ceaa3177e2..0e5fcc12f3dc 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
@@ -21,6 +21,11 @@ import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileTask;
+import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
@@ -30,6 +35,8 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.maven.project.MavenResourceCompilerConfigurationGenerator;
+import org.jetbrains.plugins.gradle.config.GradleResourceCompilerConfigurationGenerator;
import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportBuilder;
import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportProvider;
@@ -52,9 +59,22 @@ public class GradleStartupActivity implements StartupActivity {
private static final String DO_NOT_SHOW_EVENT_DESCRIPTION = "do.not.show";
@Override
- public void runActivity(@NotNull Project project) {
+ public void runActivity(@NotNull final Project project) {
configureBuildClasspath(project);
showNotificationForUnlinkedGradleProject(project);
+ CompilerManager.getInstance(project).addBeforeTask(new CompileTask() {
+ @Override
+ public boolean execute(CompileContext context) {
+ AccessToken token = ReadAction.start();
+ try {
+ new GradleResourceCompilerConfigurationGenerator(project, context).generateBuildConfiguration();
+ }
+ finally {
+ token.finish();
+ }
+ return true;
+ }
+ });
}
private static void configureBuildClasspath(@NotNull final Project project) {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectResolverContext.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectResolverContext.java
index b7f94dd57122..3aa0027185bf 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectResolverContext.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectResolverContext.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.model.idea.IdeaModule;
+import org.gradle.tooling.model.idea.IdeaProject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
@@ -93,7 +94,12 @@ public class ProjectResolverContext {
}
@Nullable
- public <T> T getExtraProject(@NotNull IdeaModule module, Class<T> modelClazz) {
+ public <T> T getExtraProject(Class<T> modelClazz) {
+ return myModels.getExtraProject(null, modelClazz);
+ }
+
+ @Nullable
+ public <T> T getExtraProject(@Nullable IdeaModule module, Class<T> modelClazz) {
return myModels.getExtraProject(module, modelClazz);
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectDataService.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectDataService.java
new file mode 100644
index 000000000000..fae9ee0d88c1
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectDataService.java
@@ -0,0 +1,233 @@
+/*
+ * 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.gradle.service.project.data;
+
+import com.intellij.CommonBundle;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.model.*;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
+import com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask;
+import com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationManager;
+import com.intellij.openapi.externalSystem.service.notification.NotificationSource;
+import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
+import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
+import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
+import com.intellij.openapi.externalSystem.util.*;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ConcurrentFactoryMap;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/17/2014
+ */
+@Order(ExternalSystemConstants.BUILTIN_SERVICE_ORDER)
+public class ExternalProjectDataService implements ProjectDataService<ExternalProject, Project> {
+ private static final Logger LOG = Logger.getInstance(ExternalProjectDataService.class);
+
+ @NotNull public static final Key<ExternalProject> KEY = Key.create(ExternalProject.class, ProjectKeys.TASK.getProcessingWeight() + 1);
+
+ @NotNull private final Map<Pair<ProjectSystemId, File>, ExternalProject> myExternalRootProjects;
+
+ @NotNull private ProjectDataManager myProjectDataManager;
+
+ public ExternalProjectDataService(@NotNull ProjectDataManager projectDataManager) {
+ myProjectDataManager = projectDataManager;
+ myExternalRootProjects = new ConcurrentFactoryMap<Pair<ProjectSystemId, File>, ExternalProject>() {
+ @Nullable
+ @Override
+ protected ExternalProject create(Pair<ProjectSystemId, File> key) {
+ return new ExternalProjectSerializer().load(key.first, key.second);
+ }
+
+ @Override
+ public ExternalProject put(Pair<ProjectSystemId, File> key, ExternalProject value) {
+ new ExternalProjectSerializer().save(value);
+ return super.put(key, value);
+ }
+ };
+ }
+
+ @NotNull
+ @Override
+ public Key<ExternalProject> getTargetDataKey() {
+ return KEY;
+ }
+
+ public void importData(@NotNull final Collection<DataNode<ExternalProject>> toImport,
+ @NotNull final Project project,
+ final boolean synchronous) {
+ if (toImport.size() != 1) {
+ throw new IllegalArgumentException(
+ String.format("Expected to get a single external project but got %d: %s", toImport.size(), toImport));
+ }
+ saveExternalProject(toImport.iterator().next().getData());
+ }
+
+ @Override
+ public void removeData(@NotNull final Collection<? extends Project> modules, @NotNull Project project, boolean synchronous) {
+ }
+
+ @Nullable
+ public ExternalProject getOrImportRootExternalProject(@NotNull Project project,
+ @NotNull ProjectSystemId systemId,
+ @NotNull File projectRootDir) {
+ final ExternalProject externalProject = getRootExternalProject(systemId, projectRootDir);
+ return externalProject != null ? externalProject : importExternalProject(project, systemId, projectRootDir);
+ }
+
+ @Nullable
+ private ExternalProject importExternalProject(@NotNull final Project project,
+ @NotNull final ProjectSystemId projectSystemId,
+ @NotNull final File projectRootDir) {
+ final Boolean result = UIUtil.invokeAndWaitIfNeeded(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ final Ref<Boolean> result = new Ref<Boolean>(false);
+ if (project.isDisposed()) return false;
+
+ final String linkedProjectPath = FileUtil.toCanonicalPath(projectRootDir.getPath());
+ final ExternalProjectSettings projectSettings =
+ ExternalSystemApiUtil.getSettings(project, projectSystemId).getLinkedProjectSettings(linkedProjectPath);
+ if (projectSettings == null) {
+ LOG.warn("Unable to get project settings for project path: " + linkedProjectPath);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Available projects paths: " + ContainerUtil.map(
+ ExternalSystemApiUtil.getSettings(project, projectSystemId).getLinkedProjectsSettings(),
+ new Function<ExternalProjectSettings, String>() {
+ @Override
+ public String fun(ExternalProjectSettings settings) {
+ return settings.getExternalProjectPath();
+ }
+ }));
+ }
+ return false;
+ }
+
+ final File projectFile = new File(linkedProjectPath);
+ final String projectName;
+ if (projectFile.isFile()) {
+ projectName = projectFile.getParentFile().getName();
+ }
+ else {
+ projectName = projectFile.getName();
+ }
+
+ // ask a user for the project import if auto-import is disabled
+ if (!projectSettings.isUseAutoImport()) {
+ String message = String.format("Project '%s' require synchronization with %s configuration. \nImport the project?",
+ projectName, projectSystemId.getReadableName());
+ int returnValue = Messages.showOkCancelDialog(
+ message, "Import Project", CommonBundle.getOkButtonText(), CommonBundle.getCancelButtonText(), Messages.getQuestionIcon()
+ );
+ if (returnValue != Messages.OK) return false;
+ }
+
+ final String title = ExternalSystemBundle.message("progress.import.text", linkedProjectPath, projectSystemId.getReadableName());
+ new Task.Modal(project, title, false) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ if (project.isDisposed()) return;
+
+ ExternalSystemNotificationManager.getInstance(project)
+ .clearNotifications(null, NotificationSource.PROJECT_SYNC, projectSystemId);
+ ExternalSystemResolveProjectTask task =
+ new ExternalSystemResolveProjectTask(projectSystemId, project, linkedProjectPath, false);
+ task.execute(indicator, ExternalSystemTaskNotificationListener.EP_NAME.getExtensions());
+ if (project.isDisposed()) return;
+
+ final Throwable error = task.getError();
+ if (error != null) {
+ ExternalSystemNotificationManager.getInstance(project)
+ .processExternalProjectRefreshError(error, projectName, projectSystemId);
+ return;
+ }
+ final DataNode<ProjectData> projectDataDataNode = task.getExternalProject();
+ if (projectDataDataNode == null) return;
+
+ final Collection<DataNode<ExternalProject>> nodes = ExternalSystemApiUtil.findAll(projectDataDataNode, KEY);
+ if (nodes.size() != 1) {
+ throw new IllegalArgumentException(
+ String.format("Expected to get a single external project but got %d: %s", nodes.size(), nodes));
+ }
+
+ ProjectRootManagerEx.getInstanceEx(myProject).mergeRootsChangesDuring(new Runnable() {
+ @Override
+ public void run() {
+ myProjectDataManager.importData(KEY, nodes, project, true);
+ }
+ });
+
+ result.set(true);
+ }
+ }.queue();
+
+ return result.get();
+ }
+ });
+
+ return result ? getRootExternalProject(projectSystemId, projectRootDir) : null;
+ }
+
+ @Nullable
+ public ExternalProject getRootExternalProject(@NotNull ProjectSystemId systemId, @NotNull File projectRootDir) {
+ return myExternalRootProjects.get(Pair.create(systemId, projectRootDir));
+ }
+
+ public void saveExternalProject(@NotNull ExternalProject externalProject) {
+ myExternalRootProjects.put(
+ Pair.create(new ProjectSystemId(externalProject.getExternalSystemId()), externalProject.getProjectDir()),
+ new DefaultExternalProject(externalProject)
+ );
+ }
+
+ @Nullable
+ public ExternalProject findExternalProject(@NotNull ExternalProject parentProject, @NotNull Module module) {
+ String externalProjectId = ExternalSystemApiUtil.getExternalProjectId(module);
+ return externalProjectId != null ? findExternalProject(parentProject, externalProjectId) : null;
+ }
+
+ @Nullable
+ private static ExternalProject findExternalProject(@NotNull ExternalProject parentProject, @NotNull String externalProjectId) {
+ if (parentProject.getQName().equals(externalProjectId)) return parentProject;
+ if (parentProject.getChildProjects().containsKey(externalProjectId)) {
+ return parentProject.getChildProjects().get(externalProjectId);
+ }
+ for (ExternalProject externalProject : parentProject.getChildProjects().values()) {
+ final ExternalProject project = findExternalProject(externalProject, externalProjectId);
+ if (project != null) return project;
+ }
+ return null;
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java
new file mode 100644
index 000000000000..8828b9ef5880
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java
@@ -0,0 +1,262 @@
+/*
+ * 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.gradle.service.project.data;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import com.esotericsoftware.kryo.serializers.CollectionSerializer;
+import com.esotericsoftware.kryo.serializers.DefaultSerializers;
+import com.esotericsoftware.kryo.serializers.FieldSerializer;
+import com.esotericsoftware.kryo.serializers.MapSerializer;
+import com.esotericsoftware.minlog.Log;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.model.*;
+import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.StreamUtil;
+import gnu.trove.THashMap;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.objenesis.strategy.StdInstantiatorStrategy;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.util.*;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/15/2014
+ */
+public class ExternalProjectSerializer {
+ private static final Logger LOG = Logger.getInstance(ExternalProjectSerializer.class);
+
+ private final Kryo myKryo;
+
+ public ExternalProjectSerializer() {
+ myKryo = new Kryo() {
+ @Override
+ public <T> T newInstance(Class<T> type) {
+ LOG.error("Serializing default type: " + type);
+ return super.newInstance(type);
+ }
+ };
+ configureKryo();
+ }
+
+ private void configureKryo() {
+ myKryo.setAutoReset(true);
+
+ myKryo.setRegistrationRequired(true);
+ Log.set(Log.LEVEL_WARN);
+
+ myKryo.register(ArrayList.class, new CollectionSerializer() {
+ @Override
+ protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
+ return new ArrayList();
+ }
+ });
+ myKryo.register(HashMap.class, new MapSerializer() {
+ @Override
+ protected Map create(Kryo kryo, Input input, Class<Map> type) {
+ return new HashMap();
+ }
+ });
+ myKryo.register(HashSet.class, new CollectionSerializer() {
+ @Override
+ protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
+ return new HashSet();
+ }
+ });
+
+ myKryo.register(File.class, new FileSerializer());
+ myKryo.register(DefaultExternalProject.class, new FieldSerializer<DefaultExternalProject>(myKryo, DefaultExternalProject.class) {
+ @Override
+ protected DefaultExternalProject create(Kryo kryo, Input input, Class<DefaultExternalProject> type) {
+ return new DefaultExternalProject();
+ }
+ });
+
+ myKryo.register(DefaultExternalTask.class, new FieldSerializer<DefaultExternalTask>(myKryo, DefaultExternalTask.class) {
+ @Override
+ protected DefaultExternalTask create(Kryo kryo, Input input, Class<DefaultExternalTask> type) {
+ return new DefaultExternalTask();
+ }
+ });
+
+ myKryo.register(DefaultExternalPlugin.class, new FieldSerializer<DefaultExternalPlugin>(myKryo, DefaultExternalPlugin.class) {
+ @Override
+ protected DefaultExternalPlugin create(Kryo kryo, Input input, Class<DefaultExternalPlugin> type) {
+ return new DefaultExternalPlugin();
+ }
+ });
+
+ myKryo.register(DefaultExternalSourceSet.class, new FieldSerializer<DefaultExternalSourceSet>(myKryo, DefaultExternalSourceSet.class) {
+ @Override
+ protected DefaultExternalSourceSet create(Kryo kryo, Input input, Class<DefaultExternalSourceSet> type) {
+ return new DefaultExternalSourceSet();
+ }
+ });
+
+ myKryo.register(
+ DefaultExternalSourceDirectorySet.class,
+ new FieldSerializer<DefaultExternalSourceDirectorySet>(myKryo, DefaultExternalSourceDirectorySet.class) {
+ @Override
+ protected DefaultExternalSourceDirectorySet create(Kryo kryo, Input input, Class<DefaultExternalSourceDirectorySet> type) {
+ return new DefaultExternalSourceDirectorySet();
+ }
+ }
+ );
+
+ myKryo.register(DefaultExternalFilter.class, new FieldSerializer<DefaultExternalFilter>(myKryo, DefaultExternalFilter.class) {
+ @Override
+ protected DefaultExternalFilter create(Kryo kryo, Input input, Class<DefaultExternalFilter> type) {
+ return new DefaultExternalFilter();
+ }
+ });
+
+ myKryo.register(ExternalSystemSourceType.class, new DefaultSerializers.EnumSerializer(ExternalSystemSourceType.class));
+
+ myKryo.register(LinkedHashSet.class, new CollectionSerializer() {
+ @Override
+ protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
+ return new LinkedHashSet();
+ }
+ });
+ myKryo.register(HashSet.class, new CollectionSerializer() {
+ @Override
+ protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
+ return new HashSet();
+ }
+ });
+ myKryo.register(THashSet.class, new CollectionSerializer() {
+ @Override
+ protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
+ return new THashSet();
+ }
+ });
+ myKryo.register(Set.class, new CollectionSerializer() {
+ @Override
+ protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
+ return new HashSet();
+ }
+ });
+ myKryo.register(THashMap.class, new MapSerializer() {
+ @Override
+ protected Map create(Kryo kryo, Input input, Class<Map> type) {
+ return new THashMap();
+ }
+ });
+ }
+
+
+ public void save(@NotNull ExternalProject externalProject) {
+ Output output = null;
+ try {
+ final String externalProjectPath = externalProject.getProjectDir().getPath();
+ final File configurationFile =
+ getProjectConfigurationFile(new ProjectSystemId(externalProject.getExternalSystemId()), externalProjectPath);
+ if (!FileUtil.createParentDirs(configurationFile)) return;
+
+ output = new Output(new FileOutputStream(configurationFile));
+ myKryo.writeObject(output, externalProject);
+ }
+ catch (FileNotFoundException e) {
+ LOG.error(e);
+ }
+ finally {
+ StreamUtil.closeStream(output);
+ }
+ }
+
+ @Nullable
+ public ExternalProject load(@NotNull ProjectSystemId externalSystemId, File externalProjectPath) {
+ Input input = null;
+ try {
+ final File configurationFile = getProjectConfigurationFile(externalSystemId, externalProjectPath.getPath());
+ if (!configurationFile.isFile()) return null;
+
+ input = new Input(new FileInputStream(configurationFile));
+ return myKryo.readObject(input, DefaultExternalProject.class);
+ }
+ catch (Exception e) {
+ LOG.error(e);
+ }
+ finally {
+ StreamUtil.closeStream(input);
+ }
+
+ return null;
+ }
+
+ private static File getProjectConfigurationFile(ProjectSystemId externalSystemId, String externalProjectPath) {
+ return new File(getProjectConfigurationDir(externalSystemId), Integer.toHexString(externalProjectPath.hashCode()) + "/project.dat");
+ }
+
+ private static File getProjectConfigurationDir(ProjectSystemId externalSystemId) {
+ return getPluginSystemDir(externalSystemId, "Projects");
+ }
+
+ private static File getPluginSystemDir(ProjectSystemId externalSystemId, String folder) {
+ return new File(PathManager.getSystemPath(), externalSystemId.getId().toLowerCase() + "/" + folder).getAbsoluteFile();
+ }
+
+ private static class FileSerializer extends Serializer<File> {
+ private final Kryo myStdKryo;
+
+ public FileSerializer() {
+ myStdKryo = new Kryo();
+ myStdKryo.register(File.class);
+ myStdKryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
+ }
+
+ @Override
+ public void write(Kryo kryo, Output output, File object) {
+ myStdKryo.writeObject(output, object);
+ }
+
+ @Override
+ public File read(Kryo kryo, Input input, Class<File> type) {
+ File file = myStdKryo.readObject(input, File.class);
+ return new File(file.getPath());
+ }
+ }
+
+ private static class StdSerializer<T> extends Serializer<T> {
+ private final Kryo myStdKryo;
+
+ public StdSerializer(Class<T> clazz) {
+ myStdKryo = new Kryo();
+ myStdKryo.register(clazz);
+ myStdKryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
+ }
+
+ @Override
+ public void write(Kryo kryo, Output output, T object) {
+ myStdKryo.writeObject(output, object);
+ }
+
+ @Override
+ public T read(Kryo kryo, Input input, Class<T> type) {
+ return myStdKryo.readObject(input, type);
+ }
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectOpenProcessor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectOpenProcessor.java
index 213ba84271ef..10f766cc5e34 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectOpenProcessor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectOpenProcessor.java
@@ -16,17 +16,26 @@
package org.jetbrains.plugins.gradle.service.project.wizard;
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
-import com.intellij.ide.util.projectWizard.ProjectBuilder;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.ide.wizard.Step;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.externalSystem.service.project.wizard.SelectExternalProjectStep;
-import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.projectImport.ProjectOpenProcessorBase;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.service.settings.GradleProjectSettingsControl;
+import org.jetbrains.plugins.gradle.service.settings.GradleSystemSettingsControl;
+import org.jetbrains.plugins.gradle.service.settings.ImportFromGradleControl;
+import org.jetbrains.plugins.gradle.settings.DistributionType;
+import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
+import org.jetbrains.plugins.gradle.settings.GradleSettings;
import org.jetbrains.plugins.gradle.util.GradleConstants;
+import static org.jetbrains.plugins.gradle.util.GradleEnvironment.Headless.*;
/**
* @author Denis Zhdanov
@@ -61,24 +70,90 @@ public class GradleProjectOpenProcessor extends ProjectOpenProcessorBase<GradleP
@Override
protected boolean doQuickImport(VirtualFile file, WizardContext wizardContext) {
- AddModuleWizard dialog = new AddModuleWizard(null, file.getPath(), new GradleProjectImportProvider(getBuilder()));
+ final GradleProjectImportProvider projectImportProvider = new GradleProjectImportProvider(getBuilder());
+ getBuilder().setFileToImport(file.getPath());
getBuilder().prepare(wizardContext);
getBuilder().getControl(null).setLinkedProjectPath(file.getPath());
- dialog.getWizardContext().setProjectBuilder(getBuilder());
- dialog.navigateToStep(new Function<Step, Boolean>() {
- @Override
- public Boolean fun(Step step) {
- return step instanceof SelectExternalProjectStep;
- }
- });
- boolean result = dialog.showAndGet();
+ final boolean result;
+ if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
+ result = setupGradleProjectSettingsInHeadlessMode(file, projectImportProvider, wizardContext);
+ }
+ else {
+ AddModuleWizard dialog = new AddModuleWizard(null, file.getPath(), projectImportProvider);
+ dialog.getWizardContext().setProjectBuilder(getBuilder());
+ dialog.navigateToStep(new Function<Step, Boolean>() {
+ @Override
+ public Boolean fun(Step step) {
+ return step instanceof SelectExternalProjectStep;
+ }
+ });
+ result = dialog.showAndGet();
+ }
if (result && getBuilder().getExternalProjectNode() != null) {
wizardContext.setProjectName(getBuilder().getExternalProjectNode().getData().getInternalName());
}
return result;
}
+ private boolean setupGradleProjectSettingsInHeadlessMode(VirtualFile file,
+ GradleProjectImportProvider projectImportProvider,
+ WizardContext wizardContext) {
+ final ModuleWizardStep[] wizardSteps = projectImportProvider.createSteps(wizardContext);
+ if (wizardSteps.length > 0 && wizardSteps[0] instanceof SelectExternalProjectStep) {
+ SelectExternalProjectStep selectExternalProjectStep = (SelectExternalProjectStep)wizardSteps[0];
+ wizardContext.setProjectBuilder(getBuilder());
+ try {
+ selectExternalProjectStep.updateStep();
+ final ImportFromGradleControl importFromGradleControl = getBuilder().getControl(wizardContext.getProject());
+
+ GradleProjectSettingsControl gradleProjectSettingsControl =
+ (GradleProjectSettingsControl)importFromGradleControl.getProjectSettingsControl();
+
+ final GradleProjectSettings projectSettings = gradleProjectSettingsControl.getInitialSettings();
+
+ if (GRADLE_DISTRIBUTION_TYPE != null) {
+ for (DistributionType type : DistributionType.values()) {
+ if (type.name().equals(GRADLE_DISTRIBUTION_TYPE)) {
+ projectSettings.setDistributionType(type);
+ break;
+ }
+ }
+ }
+ if (GRADLE_HOME != null) {
+ projectSettings.setGradleHome(GRADLE_HOME);
+ }
+ gradleProjectSettingsControl.reset();
+
+ final GradleSystemSettingsControl systemSettingsControl =
+ (GradleSystemSettingsControl)importFromGradleControl.getSystemSettingsControl();
+ assert systemSettingsControl != null;
+ final GradleSettings gradleSettings = systemSettingsControl.getInitialSettings();
+ if (GRADLE_VM_OPTIONS != null) {
+ gradleSettings.setGradleVmOptions(GRADLE_VM_OPTIONS);
+ }
+ if (GRADLE_OFFLINE != null) {
+ gradleSettings.setOfflineWork(Boolean.parseBoolean(GRADLE_OFFLINE));
+ }
+ String serviceDirectory = GRADLE_SERVICE_DIRECTORY;
+ if (GRADLE_SERVICE_DIRECTORY != null) {
+ gradleSettings.setServiceDirectoryPath(serviceDirectory);
+ }
+ systemSettingsControl.reset();
+
+ if (!selectExternalProjectStep.validate()) {
+ return false;
+ }
+ }
+ catch (ConfigurationException e) {
+ Messages.showErrorDialog(wizardContext.getProject(), e.getMessage(), e.getTitle());
+ return false;
+ }
+ selectExternalProjectStep.updateDataModel();
+ }
+ return true;
+ }
+
@Override
public boolean lookForProjectsInDirectory() {
return false;
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java
index ffdf37c74b87..ab6454c46c99 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java
@@ -173,4 +173,9 @@ public class GradleSystemSettingsControl implements ExternalSystemSettingsContro
public void disposeUIResources() {
ExternalSystemUiUtil.disposeUi(this);
}
+
+ @NotNull
+ public GradleSettings getInitialSettings() {
+ return myInitialSettings;
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java
index 2c61ac6c10eb..eb780ced4d5a 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleEnvironment.java
@@ -13,6 +13,18 @@ public class GradleEnvironment {
@NonNls public static final boolean DISABLE_ENHANCED_TOOLING_API = Boolean.getBoolean("gradle.disable.enhanced.tooling.api");
@NonNls public static final boolean ADJUST_USER_DIR = Boolean.getBoolean("gradle.adjust.userdir");
+ public static class Headless {
+ @NonNls public static final String GRADLE_DISTRIBUTION_TYPE = System.getProperty("idea.gradle.distributionType");
+ @NonNls public static final String GRADLE_HOME = System.getProperty("idea.gradle.home");
+ @NonNls public static final String GRADLE_VM_OPTIONS = System.getProperty("idea.gradle.vmOptions");
+ @NonNls public static final String GRADLE_OFFLINE = System.getProperty("idea.gradle.offline");
+ @NonNls public static final String GRADLE_SERVICE_DIRECTORY = System.getProperty("idea.gradle.serviceDirectory");
+
+ private Headless() {
+ }
+ }
+
+
private GradleEnvironment() {
}
}