diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleContentRootManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleContentRootManager.java index 1d40834f1a14..d062f821f762 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleContentRootManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleContentRootManager.java @@ -1,18 +1,18 @@ package org.jetbrains.plugins.gradle.manage; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.model.gradle.GradleContentRoot; import org.jetbrains.plugins.gradle.model.gradle.SourceType; import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot; import org.jetbrains.plugins.gradle.util.GradleUtil; +import java.util.Collection; import java.util.Collections; /** @@ -28,76 +28,59 @@ public class GradleContentRootManager { } @SuppressWarnings("MethodMayBeStatic") - public void importContentRoots(@NotNull final Iterable contentRoots, @NotNull final Module module) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - doImportContentRoots(contentRoots, module); - } - }); - } - - private static void doImportContentRoots(@NotNull final Iterable contentRoots, @NotNull final Module module) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void importContentRoots(@NotNull final Collection contentRoots, @NotNull final Module module) { + if (contentRoots.isEmpty()) { + return; + } + GradleUtil.executeProjectChangeAction(module.getProject(), contentRoots, new Runnable() { @Override public void run() { final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); final ModifiableRootModel model = moduleRootManager.getModifiableModel(); - GradleUtil.executeProjectChangeAction(module.getProject(), contentRoots, new Runnable() { - @Override - public void run() { - try { - for (GradleContentRoot contentRoot : contentRoots) { - ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath())); - for (String path : contentRoot.getPaths(SourceType.SOURCE)) { - contentEntry.addSourceFolder(toVfsUrl(path), false); - } - for (String path : contentRoot.getPaths(SourceType.TEST)) { - contentEntry.addSourceFolder(toVfsUrl(path), true); - } - for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) { - contentEntry.addExcludeFolder(toVfsUrl(path)); - } - } + try { + for (GradleContentRoot contentRoot : contentRoots) { + ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath())); + for (String path : contentRoot.getPaths(SourceType.SOURCE)) { + contentEntry.addSourceFolder(toVfsUrl(path), false); + } + for (String path : contentRoot.getPaths(SourceType.TEST)) { + contentEntry.addSourceFolder(toVfsUrl(path), true); + } + for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) { + contentEntry.addExcludeFolder(toVfsUrl(path)); } - finally { - model.commit(); - } } - }); + } + finally { + model.commit(); + } } }); } - + private static String toVfsUrl(@NotNull String path) { return LocalFileSystem.PROTOCOL_PREFIX + path; } @SuppressWarnings("MethodMayBeStatic") - public void removeContentRoots(@NotNull final Iterable contentRoots) { - UIUtil.invokeLaterIfNeeded(new Runnable() { + public void removeContentRoots(@NotNull final Collection contentRoots) { + if (contentRoots.isEmpty()) { + return; + } + Project project = contentRoots.iterator().next().getModule().getProject(); + GradleUtil.executeProjectChangeAction(project, contentRoots, new Runnable() { @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - for (final ModuleAwareContentRoot contentRoot : contentRoots) { - GradleUtil.executeProjectChangeAction(contentRoot.getModule().getProject(), contentRoot, new Runnable() { - @Override - public void run() { - final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(contentRoot.getModule()); - ModifiableRootModel model = moduleRootManager.getModifiableModel(); - try { - model.removeContentEntry(contentRoot); - } - finally { - model.commit(); - } - } - }); - } + for (ModuleAwareContentRoot contentRoot : contentRoots) { + final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(contentRoot.getModule()); + ModifiableRootModel model = moduleRootManager.getModifiableModel(); + try { + model.removeContentEntry(contentRoot); } - }); + finally { + model.commit(); + } + } } }); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleDependencyManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleDependencyManager.java index 4fa493f1c634..f8ec9ac9121b 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleDependencyManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleDependencyManager.java @@ -1,20 +1,16 @@ package org.jetbrains.plugins.gradle.manage; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.config.PlatformFacade; import org.jetbrains.plugins.gradle.model.gradle.*; import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper; import org.jetbrains.plugins.gradle.util.GradleUtil; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; /** * Thread-safe. @@ -23,17 +19,19 @@ import java.util.List; * @since 2/7/12 3:23 PM */ public class GradleDependencyManager { - - @NotNull private final PlatformFacade myPlatformFacade; - public GradleDependencyManager(@NotNull PlatformFacade platformFacade) { + @NotNull private final PlatformFacade myPlatformFacade; + @NotNull private final GradleLibraryManager myLibraryManager; + + public GradleDependencyManager(@NotNull PlatformFacade platformFacade, @NotNull GradleLibraryManager manager) { myPlatformFacade = platformFacade; + myLibraryManager = manager; } public void importDependency(@NotNull GradleDependency dependency, @NotNull Module module) { importDependencies(Collections.singleton(dependency), module); } - + public void importDependencies(@NotNull Iterable dependencies, @NotNull Module module) { final List moduleDependencies = new ArrayList(); final List libraryDependencies = new ArrayList(); @@ -56,19 +54,12 @@ public class GradleDependencyManager { } @SuppressWarnings("MethodMayBeStatic") - public void importModuleDependencies(@NotNull final Iterable dependencies, @NotNull final Module module) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - doImportModuleDependencies(dependencies, module); - } - }); - } - - private static void doImportModuleDependencies(@NotNull final Iterable dependencies, - @NotNull final Module module) - { - ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void importModuleDependencies(@NotNull final Collection dependencies, @NotNull final Module module) { + if (dependencies.isEmpty()) { + return; + } + + GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, new Runnable() { @Override public void run() { ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); @@ -77,12 +68,20 @@ public class GradleDependencyManager { final GradleProjectStructureHelper projectStructureHelper = module.getProject().getComponent(GradleProjectStructureHelper.class); for (GradleModuleDependency dependency : dependencies) { final String moduleName = dependency.getName(); - final Module intellijModuleDependency = projectStructureHelper.findIntellijModule(moduleName); - if (intellijModuleDependency == null) { + final Module intellijModule = projectStructureHelper.findIntellijModule(moduleName); + if (intellijModule == null) { assert false; continue; } - final ModuleOrderEntry orderEntry = moduleRootModel.addModuleOrderEntry(intellijModuleDependency); + else if (intellijModule.equals(module)) { + // Gradle api returns recursive module dependencies (a module depends on itself) for 'gradle' project. + continue; + } + + ModuleOrderEntry orderEntry = projectStructureHelper.findIntellijModuleDependency(dependency, moduleRootModel); + if (orderEntry == null) { + orderEntry = moduleRootModel.addModuleOrderEntry(intellijModule); + } orderEntry.setScope(dependency.getScope()); orderEntry.setExported(dependency.isExported()); } @@ -93,97 +92,79 @@ public class GradleDependencyManager { } }); } - + public void importLibraryDependencies(@NotNull final Iterable dependencies, @NotNull final Module module) { - final List infos = new ArrayList(); - final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject()); - for (GradleLibraryDependency dependency : dependencies) { - final Library library = libraryTable.getLibraryByName(dependency.getName()); - if (library != null) { - infos.add(new LibraryDependencyInfo(library, dependency.getScope(), dependency.isExported())); - } - } - doImportLibraryDependencies(infos, module); - } - - private static void doImportLibraryDependencies(@NotNull final Iterable infos, @NotNull final Module module) { - UIUtil.invokeLaterIfNeeded(new Runnable() { + GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, new Runnable() { @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - GradleUtil.executeProjectChangeAction(module.getProject(), infos, new Runnable() { - @Override - public void run() { - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); - final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); - try { - for (LibraryDependencyInfo info : infos) { - LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(info.library); - orderEntry.setExported(info.exported); - orderEntry.setScope(info.scope); - } - } - finally { - moduleRootModel.commit(); - } - } - }); + LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject()); + Set librariesToImport = new HashSet(); + for (GradleLibraryDependency dependency : dependencies) { + final Library library = libraryTable.getLibraryByName(dependency.getName()); + if (library == null) { + librariesToImport.add(dependency.getTarget()); } - }); + } + if (!librariesToImport.isEmpty()) { + myLibraryManager.importLibraries(librariesToImport, module.getProject()); + } + + for (GradleLibraryDependency dependency : dependencies) { + GradleProjectStructureHelper helper = module.getProject().getComponent(GradleProjectStructureHelper.class); + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); + try { + libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject()); + final Library library = libraryTable.getLibraryByName(dependency.getName()); + if (library == null) { + assert false; + continue; + } + LibraryOrderEntry orderEntry = helper.findIntellijLibraryDependency(dependency.getName(), moduleRootModel); + if (orderEntry == null) { + // We need to get the most up-to-date Library object due to our project model restrictions. + orderEntry = moduleRootModel.addLibraryEntry(library); + } + orderEntry.setExported(dependency.isExported()); + orderEntry.setScope(dependency.getScope()); + } + finally { + moduleRootModel.commit(); + } + } } }); } @SuppressWarnings("MethodMayBeStatic") - public void removeDependencies(@NotNull final Iterable dependencies) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - for (final ExportableOrderEntry dependency : dependencies) { - final Module module = dependency.getOwnerModule(); - GradleUtil.executeProjectChangeAction(module.getProject(), dependency, new Runnable() { - @Override - public void run() { - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); - final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); - try { - // The thing is that intellij created order entry objects every time new modifiable model is created, - // that's why we can't use target dependency object as is but need to get a reference to the current - // entry object from the model instead. - for (OrderEntry entry : moduleRootModel.getOrderEntries()) { - if (entry.getPresentableName().equals(dependency.getPresentableName())) { - moduleRootModel.removeOrderEntry(entry); - break; - } - } - } - finally { - moduleRootModel.commit(); - } - } - }); + public void removeDependencies(@NotNull final Collection dependencies) { + if (dependencies.isEmpty()) { + return; + } + + for (final ExportableOrderEntry dependency : dependencies) { + final Module module = dependency.getOwnerModule(); + GradleUtil.executeProjectChangeAction(module.getProject(), dependency, new Runnable() { + @Override + public void run() { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); + try { + // The thing is that intellij created order entry objects every time new modifiable model is created, + // that's why we can't use target dependency object as is but need to get a reference to the current + // entry object from the model instead. + for (OrderEntry entry : moduleRootModel.getOrderEntries()) { + if (entry.getPresentableName().equals(dependency.getPresentableName())) { + moduleRootModel.removeOrderEntry(entry); + break; + } } } - }); - } - }); - } - - private static class LibraryDependencyInfo { - - @NotNull public final Library library; - @NotNull public final DependencyScope scope; - public final boolean exported; - - LibraryDependencyInfo(@NotNull Library library, @NotNull DependencyScope scope, boolean exported) { - this.library = library; - this.scope = scope; - this.exported = exported; + finally { + moduleRootModel.commit(); + } + } + }); } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLibraryManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLibraryManager.java index b749ebebb165..c0b38fae255e 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLibraryManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLibraryManager.java @@ -1,23 +1,21 @@ package org.jetbrains.plugins.gradle.manage; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.JavadocOrderRootType; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.NotNullFunction; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.config.PlatformFacade; import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary; import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType; import org.jetbrains.plugins.gradle.util.GradleLog; +import org.jetbrains.plugins.gradle.util.GradleUtil; import java.io.File; import java.util.*; @@ -34,8 +32,13 @@ public class GradleLibraryManager { myPlatformFacade = platformFacade; } - @NotNull - public Library importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project) { + public void importLibraries(@NotNull Collection libraries, @NotNull Project project) { + for (GradleLibrary library : libraries) { + importLibrary(library, project); + } + } + + public void importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project) { Map> libraryFiles = new HashMap>(); for (LibraryPathType pathType : LibraryPathType.values()) { final Set paths = library.getPaths(pathType); @@ -50,47 +53,22 @@ public class GradleLibraryManager { } })); } - return importLibrary(library.getName(), libraryFiles, project); + importLibrary(library.getName(), libraryFiles, project); } - @NotNull - public Library importLibrary(@NotNull final String libraryName, - @NotNull final Map> libraryFiles, - @NotNull final Project project) + public void importLibrary(@NotNull final String libraryName, + @NotNull final Map> libraryFiles, + @NotNull final Project project) { - final Ref result = new Ref(); - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); - publisher.onChangeStart(libraryName); - try { - result.set(doImportLibrary(libraryName, libraryFiles, project)); - } - finally { - publisher.onChangeEnd(libraryName); - } - } - }); - return result.get(); - } - - @NotNull - private Library doImportLibrary(@NotNull final String libraryName, - @NotNull final Map> libraryFiles, - @NotNull Project project) - { - // Is assumed to be called from the EDT. - final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project); - final Ref result = new Ref(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { + GradleUtil.executeProjectChangeAction(project, libraryName, new Runnable() { @Override public void run() { + // Is assumed to be called from the EDT. + final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project); final LibraryTable.ModifiableModel projectLibraryModel = libraryTable.getModifiableModel(); final Library intellijLibrary; try { intellijLibrary = projectLibraryModel.createLibrary(libraryName); - result.set(intellijLibrary); } finally { projectLibraryModel.commit(); @@ -104,7 +82,6 @@ public class GradleLibraryManager { } } }); - return result.get(); } private static void registerPaths(@NotNull final Map> libraryFiles, @@ -115,9 +92,9 @@ public class GradleLibraryManager { for (File file : entry.getValue()) { VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file); if (virtualFile == null) { - GradleLog.LOG.warn( - String.format("Can't find %s of the library '%s' at path '%s'", entry.getKey(), libraryName, file.getAbsolutePath()) - ); + //GradleLog.LOG.warn( + // String.format("Can't find %s of the library '%s' at path '%s'", entry.getKey(), libraryName, file.getAbsolutePath()) + //); continue; } if (virtualFile.isDirectory()) { @@ -137,7 +114,7 @@ public class GradleLibraryManager { } } - public void removeLibraries(@NotNull List libraries) { + public void removeLibraries(@NotNull List libraries) { // TODO den implement //LibraryTable table = library.getTable(); //table.removeLibrary(library); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModuleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModuleManager.java index 0ffc42f734cb..916ee0057597 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModuleManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModuleManager.java @@ -16,6 +16,7 @@ import org.jetbrains.plugins.gradle.util.GradleLog; import org.jetbrains.plugins.gradle.util.GradleUtil; import java.io.File; +import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -50,7 +51,13 @@ public class GradleModuleManager { importModules(Collections.singleton(module), project, false); } - public void importModules(@NotNull final Iterable modules, @NotNull final Project project, final boolean recursive) { + public void importModules(@NotNull final Collection modules, + @NotNull final Project project, + final boolean recursive) + { + if (modules.isEmpty()) { + return; + } if (!project.isInitialized()) { myAlarm.addRequest(new ImportModulesTask(project, modules, recursive), PROJECT_INITIALISATION_DELAY_MS); return; @@ -65,7 +72,7 @@ public class GradleModuleManager { @Override public void run() { final ModuleManager moduleManager = ModuleManager.getInstance(project); - final GradleProjectEntityChangeListener publisher + final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); for (GradleModule module : modules) { publisher.onChangeStart(module); @@ -121,7 +128,7 @@ public class GradleModuleManager { }); } - private static void removeExistingModulesConfigs(@NotNull Iterable modules) { + private static void removeExistingModulesConfigs(@NotNull Collection modules) { for (GradleModule module : modules) { // Remove existing '*.iml' file if necessary. final String moduleFilePath = module.getModuleFilePath(); @@ -136,43 +143,37 @@ public class GradleModuleManager { } @SuppressWarnings("MethodMayBeStatic") - public void removeModules(@NotNull final Iterable modules) { - UIUtil.invokeLaterIfNeeded(new Runnable() { + public void removeModules(@NotNull final Collection modules) { + if (modules.isEmpty()) { + return; + } + Project project = modules.iterator().next().getProject(); + GradleUtil.executeProjectChangeAction(project, modules, new Runnable() { @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - for (final Module module : modules) { - GradleUtil.executeProjectChangeAction(module.getProject(), module, new Runnable() { - @Override - public void run() { - ModuleManager moduleManager = ModuleManager.getInstance(module.getProject()); - String path = module.getModuleFilePath(); - moduleManager.disposeModule(module); - File file = new File(path); - if (file.isFile()) { - boolean success = file.delete(); - if (!success) { - GradleLog.LOG.warn("Can't remove module file at '" + path + "'"); - } - } - } - }); - } + for (Module module : modules) { + ModuleManager moduleManager = ModuleManager.getInstance(module.getProject()); + String path = module.getModuleFilePath(); + moduleManager.disposeModule(module); + File file = new File(path); + if (file.isFile()) { + boolean success = file.delete(); + if (!success) { + GradleLog.LOG.warn("Can't remove module file at '" + path + "'"); + } } - }); + } } }); } private class ImportModulesTask implements Runnable { - private final Project myProject; - private final Iterable myModules; - private final boolean myRecursive; + private final Project myProject; + private final Collection myModules; + private final boolean myRecursive; - ImportModulesTask(@NotNull Project project, @NotNull Iterable modules, boolean recursive) { + ImportModulesTask(@NotNull Project project, @NotNull Collection modules, boolean recursive) { myProject = project; myModules = modules; myRecursive = recursive; @@ -192,5 +193,4 @@ public class GradleModuleManager { importModules(myModules, myProject, myRecursive); } } - } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModulesImporter.java deleted file mode 100644 index f55af6110203..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModulesImporter.java +++ /dev/null @@ -1,564 +0,0 @@ -package org.jetbrains.plugins.gradle.manage; - -import com.intellij.openapi.application.*; -import com.intellij.openapi.module.ModifiableModuleModel; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.module.StdModuleTypes; -import com.intellij.openapi.roots.impl.ModifiableModelCommitter; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.*; -import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Alarm; -import com.intellij.util.containers.hash.HashMap; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.gradle.model.gradle.*; -import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel; -import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask; -import org.jetbrains.plugins.gradle.util.GradleBundle; -import org.jetbrains.plugins.gradle.util.GradleLog; - -import java.io.File; -import java.util.*; -import java.util.concurrent.TimeUnit; - -/** - * Encapsulates functionality of creating IntelliJ IDEA modules on the basis of {@link GradleModule gradle modules}. - *

- * Not thread-safe. - * - * @author Denis Zhdanov - * @since 8/26/11 10:01 AM - */ -// TODO den remove -public class GradleModulesImporter { - - private static final Map LIBRARY_ROOT_MAPPINGS - = new EnumMap(LibraryPathType.class); - static { - LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.BINARY, OrderRootType.CLASSES); - LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.SOURCE, OrderRootType.SOURCES); - LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.DOC, JavadocOrderRootType.getInstance()); - assert LibraryPathType.values().length == LIBRARY_ROOT_MAPPINGS.size(); - } - - /** - * We can't modify project modules (add/remove) until it's initialised, so, we delay that activity. Current constant - * holds number of milliseconds to wait between 'after project initialisation' processing attempts. - */ - private static final int PROJECT_INITIALISATION_DELAY_MS = (int)TimeUnit.SECONDS.toMillis(1); - - private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); - - /** - * Entry point for the whole 'import modules' procedure. - * - * @param modules module info containers received from the gradle api - * @param project project that should host the modules - * @param model modules model - * @param gradleProjectPath file system path to the gradle project file being imported - * @return mappings between the given gradle modules and newly created intellij modules - */ - @NotNull - public Map importModules(@NotNull final Iterable modules, @Nullable final Project project, - @Nullable final ModifiableModuleModel model, @NotNull String gradleProjectPath) - { - if (project == null) { - return Collections.emptyMap(); - } - removeExistingModulesSettings(modules); - if (!project.isInitialized()) { - myAlarm.addRequest(new ImportModulesTask(project, modules, gradleProjectPath), PROJECT_INITIALISATION_DELAY_MS); - return Collections.emptyMap(); - } - if (model == null) { - return Collections.emptyMap(); - } - return importModules(modules, model, project, gradleProjectPath); - } - - private static void removeExistingModulesSettings(@NotNull Iterable modules) { - for (GradleModule module : modules) { - // Remove existing '*.iml' file if necessary. - final String moduleFilePath = module.getModuleFilePath(); - File file = new File(moduleFilePath); - if (file.isFile()) { - boolean success = file.delete(); - if (!success) { - GradleLog.LOG.warn("Can't remove existing module file at '" + moduleFilePath + "'"); - } - } - } - } - - public Map importModules(@NotNull final Iterable modules, - @NotNull final ModifiableModuleModel model, - @NotNull final Project intellijProject, - @NotNull final String gradleProjectPath) - { - final Map result = new HashMap(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - Application application = ApplicationManager.getApplication(); - AccessToken writeLock = application.acquireWriteActionLock(getClass()); - try { - final List rootModels = new ArrayList(); - final GradleProjectEntityChangeListener publisher = - intellijProject.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); - for (GradleModule module : modules) { - publisher.onChangeStart(module); - } - try { - Map moduleMappings = doImportModules(modules, model, rootModels); - result.putAll(moduleMappings); - myAlarm.cancelAllRequests(); - myAlarm.addRequest( - new SetupExternalLibrariesTask(moduleMappings, gradleProjectPath, intellijProject), - PROJECT_INITIALISATION_DELAY_MS - ); - } - finally { - ModifiableRootModel[] modelsAsArray = rootModels.toArray(new ModifiableRootModel[rootModels.size()]); - ModifiableModelCommitter.multiCommit(modelsAsArray, model); - for (GradleModule module : modules) { - publisher.onChangeEnd(module); - } - } - } - finally { - writeLock.finish(); - } - } - }); - return result; - } - - /** - * Actual implementation of {@link #importModules(Iterable, Project, ModifiableModuleModel, String)}. - * Insists on all arguments to be ready to use. - * - * @param modules modules to import - * @param model modules model - * @param rootModels holder for the module root modules. Is expected to be populated during the current method processing - * @return mappings between the given gradle modules and corresponding intellij modules - */ - @NotNull - @SuppressWarnings("MethodMayBeStatic") - private Map doImportModules(@NotNull Iterable modules, - @NotNull ModifiableModuleModel model, - @NotNull List rootModels) - { - Map result = new HashMap(); - for (GradleModule moduleToImport : modules) { - Module createdModule = createModule(moduleToImport, model); - result.put(moduleToImport, createdModule); - } - for (GradleModule moduleToImport : modules) { - ModifiableRootModel rootModel = configureModule(moduleToImport, result); - rootModels.add(rootModel); - } - return result; - } - - /** - * We need to create module objects for all modules at first and then configure them. That is necessary for setting up - * module dependencies. - * - * @param module gradle module to import - * @param model module model - * @return newly created IJ module - */ - @NotNull - private static Module createModule(@NotNull GradleModule module, @NotNull ModifiableModuleModel model) { - Application application = ApplicationManager.getApplication(); - application.assertWriteAccessAllowed(); - final String moduleFilePath = module.getModuleFilePath(); - return model.newModule(moduleFilePath, StdModuleTypes.JAVA.getId()); - } - - /** - * Applies module settings received from the gradle api (encapsulate at the given {@link GradleModule} object) to the - * target intellij module (retrieved from the given module mappings). - * - * @param module target gradle module which corresponding intellij module should be configured - * @param modules gradle module to intellij modules mappings. Is assumed to have a value for the given gradle modules used as a key - * @return module roots model used during configuration - */ - @NotNull - private static ModifiableRootModel configureModule(@NotNull GradleModule module, @NotNull Map modules) { - Application application = ApplicationManager.getApplication(); - application.assertWriteAccessAllowed(); - - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(modules.get(module)); - ModifiableRootModel rootModel = moduleRootManager.getModifiableModel(); - configureModule(module, rootModel, modules); - return rootModel; - } - - /** - * Contains actual logic of {@link #configureModule(GradleModule, Map)}. - * - * @param module target module settings holder - * @param model intellij module setting manager - * @param modules modules mappings - */ - private static void configureModule(@NotNull GradleModule module, @NotNull final ModifiableRootModel model, - @NotNull final Map modules) - { - // Ensure that dependencies are clear. - final Object key = new Object(); - final Object dummy = new Object(); - RootPolicy policy = new RootPolicy() { - @Override - public Object visitModuleSourceOrderEntry(ModuleSourceOrderEntry moduleSourceOrderEntry, Object value) { - return key; - } - }; - for (OrderEntry orderEntry : model.getOrderEntries()) { - // Don't remove 'module source' order entry (configured automatically on module creation). - if (key != orderEntry.accept(policy, dummy)) { - model.removeOrderEntry(orderEntry); - } - } - - // Configure SDK. - model.inheritSdk(); - - // Compile output. - CompilerModuleExtension compilerExtension = model.getModuleExtension(CompilerModuleExtension.class); - compilerExtension.inheritCompilerOutputPath(module.isInheritProjectCompileOutputPath()); - if (!module.isInheritProjectCompileOutputPath()) { - String compileOutputPath = module.getCompileOutputPath(SourceType.SOURCE); - String testCompileOutputPath = module.getCompileOutputPath(SourceType.TEST); - if (StringUtil.isEmpty(compileOutputPath) || StringUtil.isEmpty(testCompileOutputPath)) { - GradleLog.LOG.warn(String.format( - "Module '%s' doesn't inherit project compile output path but has incomplete local setup. Falling back to the project " - + "compile output path. Local compile output path: '%s', local test compile output path: '%s'", - module.getName(), compileOutputPath, testCompileOutputPath - )); - compilerExtension.inheritCompilerOutputPath(true); - } - else { - compilerExtension.setCompilerOutputPath(compileOutputPath); - compilerExtension.setCompilerOutputPathForTests(testCompileOutputPath); - } - } - - // Content roots. - for (GradleContentRoot contentRoot : module.getContentRoots()) { - ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath())); - for (String path : contentRoot.getPaths(SourceType.SOURCE)) { - contentEntry.addSourceFolder(toVfsUrl(path), false); - } - for (String path : contentRoot.getPaths(SourceType.TEST)) { - contentEntry.addSourceFolder(toVfsUrl(path), true); - } - for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) { - contentEntry.addExcludeFolder(toVfsUrl(path)); - } - } - - // Module dependencies. - for (GradleDependency dependency : module.getDependencies()) { - dependency.invite(new GradleEntityVisitorAdapter() { - @Override - public void visit(@NotNull GradleModuleDependency dependency) { - ModuleOrderEntry orderEntry = model.addModuleOrderEntry(modules.get(dependency.getTarget())); - orderEntry.setExported(dependency.isExported()); - orderEntry.setScope(dependency.getScope()); - } - }); - } - } - - /** - * Resolves (downloads if necessary) external libraries necessary for the gradle project located at the given path and configures - * them for the corresponding intellij project. - *

- * Note: is assumed to be executed under write action. - * - * @param moduleMappings gradle-intellij module mappings - * @param intellijProject intellij project for the target gradle project - * @param gradleProjectPath file system path to the target gradle project - */ - private static void setupLibraries(@NotNull final Map moduleMappings, - @NotNull final Project intellijProject, - @NotNull final String gradleProjectPath) - { - final Ref gradleProjectRef = new Ref(); - final Ref libraryToPreserve = new Ref(); - - final Runnable setupExternalDependenciesTask = new Runnable() { - @Override - public void run() { - final GradleProject gradleProject = gradleProjectRef.get(); - if (gradleProject == null) { - return; - } - - Application application = ApplicationManager.getApplication(); - AccessToken writeLock = application.acquireWriteActionLock(getClass()); - try { - doSetupLibraries(moduleMappings, gradleProject, intellijProject, libraryToPreserve.get()); - } - finally { - writeLock.finish(); - } - - if (intellijProject.isDisposed()) { - return; - } - - // Force refresh the infrastructure in order to apply newly introduce intellij project structure changes - final GradleProjectStructureChangesModel changesModel = intellijProject.getComponent(GradleProjectStructureChangesModel.class); - if (changesModel != null) { - final GradleProject project = changesModel.getGradleProject(); - if (project != null) { - changesModel.update(project); - } - } - } - }; - - final Runnable resolveDependenciesTask = new Runnable() { - @Override - public void run() { - ProgressManager.getInstance().run( - new Task.Backgroundable(intellijProject, GradleBundle.message("gradle.library.resolve.progress.text"), false) { - @Override - public void run(@NotNull final ProgressIndicator indicator) { - GradleResolveProjectTask task = new GradleResolveProjectTask(intellijProject, gradleProjectPath, true); - task.execute(indicator); - GradleProject projectWithResolvedLibraries = task.getGradleProject(); - gradleProjectRef.set(projectWithResolvedLibraries); - ApplicationManager.getApplication().invokeLater(setupExternalDependenciesTask, ModalityState.NON_MODAL); - } - }); - } - }; - - UIUtil.invokeLaterIfNeeded(resolveDependenciesTask); - } - - private static void doSetupLibraries(@NotNull Map moduleMappings, - @NotNull GradleProject gradleProject, - @NotNull Project intellijProject, - @Nullable Library libraryToPreserve) { - if (intellijProject.isDisposed()) { - return; - } - Application application = ApplicationManager.getApplication(); - application.assertWriteAccessAllowed(); - - LibraryTable projectLibraryTable = ProjectLibraryTable.getInstance(intellijProject); - if (projectLibraryTable == null) { - GradleLog.LOG.warn( - "Can't resolve external dependencies of the target gradle project (" + intellijProject + "). Reason: project " - + "library table is undefined" - ); - return; - } - LibraryTable.ModifiableModel model = projectLibraryTable.getModifiableModel(); - // Clean existing libraries (if any). - try { - for (Library library : model.getLibraries()) { - if (libraryToPreserve != library) { - model.removeLibrary(library); - } - } - } - finally { - model.commit(); - } - - model = projectLibraryTable.getModifiableModel(); - List modelsToCommit = new ArrayList(); - Map libraryMappings = registerProjectLibraries(gradleProject, model); - final GradleProjectEntityChangeListener publisher - = intellijProject.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); - try { - if (libraryMappings == null) { - return; - } - for (GradleLibrary library : libraryMappings.keySet()) { - publisher.onChangeStart(library); - } - modelsToCommit.addAll(configureModulesLibraryDependencies(moduleMappings, libraryMappings, gradleProject)); - } - finally { - model.commit(); - ProjectRootManager projectRootManager = ProjectRootManager.getInstance(intellijProject); - ModifiableRootModel[] modelsAsArray = modelsToCommit.toArray(new ModifiableRootModel[modelsToCommit.size()]); - if (modelsAsArray.length > 0) { - ModifiableModelCommitter.multiCommit(modelsAsArray, ModuleManager.getInstance(modelsAsArray[0].getProject()).getModifiableModel()); - } - if (libraryMappings != null) { - for (GradleLibrary library : libraryMappings.keySet()) { - publisher.onChangeEnd(library); - } - } - } - } - - /** - * Registers {@link GradleProject#getLibraries() libraries} of the given gradle project at the intellij project. - * - * @param gradleProject target gradle project being imported - * @param librariesModel model that manages project libraries - * @return mapping between libraries of the given gradle and intellij projects - */ - @Nullable - private static Map registerProjectLibraries(@NotNull GradleProject gradleProject, - @NotNull LibraryTable.ModifiableModel librariesModel) - { - Map libraryMappings = new HashMap(); - for (GradleLibrary gradleLibrary : gradleProject.getLibraries()) { - Library intellijLibrary = librariesModel.createLibrary(gradleLibrary.getName()); - libraryMappings.put(gradleLibrary, intellijLibrary); - Library.ModifiableModel model = intellijLibrary.getModifiableModel(); - try { - registerPath(gradleLibrary, model); - } - finally { - model.commit(); - } - } - return libraryMappings; - } - - private static Collection configureModulesLibraryDependencies( - @NotNull Map moduleMappings, - @NotNull final Map libraryMappings, - @NotNull GradleProject gradleProject) - { - List result = new ArrayList(); - for (GradleModule gradleModule : gradleProject.getModules()) { - Module intellijModule = moduleMappings.get(gradleModule); - if (intellijModule == null) { - GradleLog.LOG.warn(String.format( - "Can't find intellij module for the gradle module '%s'. Registered mappings: %s", gradleModule, moduleMappings - )); - continue; - } - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(intellijModule); - final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); - result.add(moduleRootModel); - GradleEntityVisitor visitor = new GradleEntityVisitorAdapter() { - @Override - public void visit(@NotNull GradleLibraryDependency dependency) { - GradleLibrary gradleLibrary = dependency.getTarget(); - Library intellijLibrary = libraryMappings.get(gradleLibrary); - if (intellijLibrary == null) { - GradleLog.LOG.warn(String.format( - "Can't find registered intellij library for gradle library '%s'. Registered mappings: %s", gradleLibrary, libraryMappings - )); - return; - } - LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(intellijLibrary); - orderEntry.setExported(dependency.isExported()); - orderEntry.setScope(dependency.getScope()); - } - }; - for (GradleDependency dependency : gradleModule.getDependencies()) { - dependency.invite(visitor); - } - } - return result; - } - - private static void registerPath(@NotNull GradleLibrary gradleLibrary, @NotNull Library.ModifiableModel model) { - for (LibraryPathType pathType : LibraryPathType.values()) { - for (String path : gradleLibrary.getPaths(pathType)) { - VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(path)); - if (virtualFile == null) { - GradleLog.LOG.warn(String.format("Can't find %s of the library '%s' at path '%s'", pathType, gradleLibrary.getName(), path)); - continue; - } - if (virtualFile.isDirectory()) { - model.addRoot(virtualFile, LIBRARY_ROOT_MAPPINGS.get(pathType)); - } - else { - VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile); - if (jarRoot == null) { - GradleLog.LOG.warn(String.format( - "Can't parse contents of the jar file at path '%s' for the library '%s''", path, gradleLibrary.getName() - )); - continue; - } - model.addRoot(jarRoot, LIBRARY_ROOT_MAPPINGS.get(pathType)); - } - } - } - } - - private static String toVfsUrl(@NotNull String path) { - return LocalFileSystem.PROTOCOL_PREFIX + path; - } - - private class ImportModulesTask implements Runnable { - - private final Project myProject; - private final Iterable myModules; - private final String myGradleProjectPath; - - ImportModulesTask(@NotNull Project project, @NotNull Iterable modules, @NotNull String gradleProjectPath) { - myProject = project; - myModules = modules; - myGradleProjectPath = gradleProjectPath; - } - - @Override - public void run() { - myAlarm.cancelAllRequests(); - if (!myProject.isInitialized()) { - myAlarm.addRequest( - new ImportModulesTask(myProject, myModules, myGradleProjectPath), - PROJECT_INITIALISATION_DELAY_MS - ); - return; - } - - final ModifiableModuleModel model = new ReadAction() { - protected void run(Result result) throws Throwable { - result.setResult(ModuleManager.getInstance(myProject).getModifiableModel()); - } - }.execute().getResultObject(); - - importModules(myModules, model, myProject, myGradleProjectPath); - } - } - - private static class SetupExternalLibrariesTask implements Runnable { - - private final Map myModules; - private final String myGradleProjectPath; - private final Project myIntellijProject; - - SetupExternalLibrariesTask(@NotNull Map modules, - @NotNull String gradleProjectPath, - @NotNull Project intellijProject) - { - myModules = modules; - myGradleProjectPath = gradleProjectPath; - myIntellijProject = intellijProject; - } - - @Override - public void run() { - setupLibraries(myModules, myIntellijProject, myGradleProjectPath); - } - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleProjectImportBuilder.java index 1dc7cbe3fed5..33edefceeefa 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleProjectImportBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleProjectImportBuilder.java @@ -4,11 +4,18 @@ import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.JavaSdk; import com.intellij.openapi.projectRoots.SdkTypeId; import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Ref; @@ -16,14 +23,17 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.artifacts.ModifiableArtifactModel; import com.intellij.pom.java.LanguageLevel; import com.intellij.projectImport.ProjectImportBuilder; +import com.intellij.util.ui.UIUtil; import icons.GradleIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.config.GradleConfigurable; import org.jetbrains.plugins.gradle.config.GradleSettings; -import org.jetbrains.plugins.gradle.model.gradle.GradleEntity; +import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary; import org.jetbrains.plugins.gradle.model.gradle.GradleModule; import org.jetbrains.plugins.gradle.model.gradle.GradleProject; +import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper; +import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleLog; @@ -31,7 +41,10 @@ import org.jetbrains.plugins.gradle.util.GradleUtil; import javax.swing.*; import java.io.File; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; /** * GoF builder for gradle-backed projects. @@ -42,12 +55,22 @@ import java.util.*; @SuppressWarnings("MethodMayBeStatic") public class GradleProjectImportBuilder extends ProjectImportBuilder { - /** @see #setModuleMappings(Map) */ - private final Map myModuleMappings = new HashMap(); - - private GradleProject myGradleProject; + @NotNull private final GradleModuleManager myModuleManager; + @NotNull private final GradleLibraryManager myLibraryManager; + @NotNull private final GradleDependencyManager myDependencyManager; + + private GradleProject myGradleProject; private GradleConfigurable myConfigurable; + public GradleProjectImportBuilder(@NotNull GradleModuleManager moduleManager, + @NotNull GradleLibraryManager libraryManager, + @NotNull GradleDependencyManager manager) + { + myModuleManager = moduleManager; + myLibraryManager = libraryManager; + myDependencyManager = manager; + } + @NotNull @Override public String getName() { @@ -93,12 +116,13 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder commit(final Project project, ModifiableModuleModel model, ModulesProvider modulesProvider, - ModifiableArtifactModel artifactModel) { + ModifiableArtifactModel artifactModel) + { System.setProperty(GradleConstants.NEWLY_IMPORTED_PROJECT, Boolean.TRUE.toString()); final GradleProject gradleProject = getGradleProject(); if (gradleProject != null) { @@ -114,15 +138,107 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder mappings = - importer.importModules(myModuleMappings.values(), project, model, projectFile.getAbsolutePath()); - return new ArrayList(mappings.values()); + /** + * The whole import sequence looks like below: + *

+ *

+   * 
    + *
  1. Get project view from the gradle tooling api without resolving dependencies (downloading libraries);
  2. + *
  3. Allow to adjust project settings before importing;
  4. + *
  5. Create IJ project and modules;
  6. + *
  7. Ask gradle tooling api to resolve library dependencies (download the if necessary);
  8. + *
  9. Configure libraries used by the gradle project at intellij;
  10. + *
  11. Configure library dependencies;
  12. + *
+ *
+ *

+ * + * @param projectWithResolvedLibraries gradle project with resolved libraries (libraries have already been downloaded and + * are available at file system under gradle service directory) + * @param project current intellij project which should be configured by libraries and module library + * dependencies information available at the given gradle project + */ + private void setupLibraries(final GradleProject projectWithResolvedLibraries, final Project project) { + final Set libraries = projectWithResolvedLibraries.getLibraries(); + GradleUtil.executeProjectChangeAction(project, libraries, new Runnable() { + @Override + public void run() { + ProjectRootManagerEx.getInstanceEx(project).mergeRootsChangesDuring(new Runnable() { + @Override + public void run() { + // Clean existing libraries (if any). + LibraryTable projectLibraryTable = ProjectLibraryTable.getInstance(project); + if (projectLibraryTable == null) { + GradleLog.LOG.warn( + "Can't resolve external dependencies of the target gradle project (" + project + "). Reason: project " + + "library table is undefined" + ); + return; + } + LibraryTable.ModifiableModel model = projectLibraryTable.getModifiableModel(); + try { + for (Library library : model.getLibraries()) { + model.removeLibrary(library); + } + } + finally { + model.commit(); + } + + // Register libraries. + myLibraryManager.importLibraries(projectWithResolvedLibraries.getLibraries(), project); + GradleProjectStructureHelper helper = project.getComponent(GradleProjectStructureHelper.class); + for (GradleModule module : projectWithResolvedLibraries.getModules()) { + Module intellijModule = helper.findIntellijModule(module); + assert intellijModule != null; + myDependencyManager.importDependencies(module.getDependencies(), intellijModule); + } + } + }); + } + }); } @Nullable @@ -206,32 +322,6 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder - *

-   * 
    - *
  1. Get project view from the gradle tooling api without resolving dependencies (downloading libraries);
  2. - *
  3. Allow to adjust project settings before importing;
  4. - *
  5. Create IJ project and modules;
  6. - *
  7. Ask gradle tooling api to resolve library dependencies (download the if necessary);
  8. - *
  9. Configure modules dependencies;
  10. - *
- *
- *

- * {@link GradleEntity} guarantees correct {@link #equals(Object)}/{@link #hashCode()} implementation, so, we expect - * to get {@link GradleModule modules} that are the same in terms of {@link #equals(Object)} on subsequent calls. However, - * end-user is allowed to change their settings before the importing (e.g. module name), so, we need to map modules with - * resolved libraries to the modules from project 'view'. That's why end-user adjusts settings of the cloned modules. - * Given collection holds mappings between them. - * - * @param mappings origin-adjusted modules mappings - */ - public void setModuleMappings(@NotNull Map mappings) { - myModuleMappings.clear(); - myModuleMappings.putAll(mappings); - } - /** * Allows to get {@link Project} instance to use. Basically, there are two alternatives - * {@link WizardContext#getProject() project from the current wizard context} and diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleAdjustImportSettingsStep.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleAdjustImportSettingsStep.java index 44c3da214b88..39dc8f4b7400 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleAdjustImportSettingsStep.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleAdjustImportSettingsStep.java @@ -188,15 +188,11 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza List modules = new ArrayList(project.getModules()); Collections.sort(modules, Named.COMPARATOR); List moduleNodes = new ArrayList(); - Map moduleMappings = new HashMap(); - GradleEntityCloneContext cloneContext = new GradleEntityCloneContext(); for (GradleModule module : modules) { - GradleModule moduleCopy = module.clone(cloneContext); - moduleMappings.put(module, moduleCopy); GradleProjectStructureNode moduleNode = buildNode(module, entity2nodes, counter++); moduleNodes.add(moduleNode); - for (GradleContentRoot contentRoot : moduleCopy.getContentRoots()) { + for (GradleContentRoot contentRoot : module.getContentRoots()) { moduleNode.add(buildNode(contentRoot, entity2nodes, counter++)); } Collection dependencies = module.getDependencies(); @@ -263,7 +259,6 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza } myTree.expandPath(new TreePath(root.getPath())); - builder.setModuleMappings(moduleMappings); } private GradleProjectStructureNode buildNode( diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleApiFacadeImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleApiFacadeImpl.java index 74ed43dd9c74..e753764fbc9a 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleApiFacadeImpl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleApiFacadeImpl.java @@ -113,7 +113,7 @@ public class GradleApiFacadeImpl extends RemoteServer implements GradleApiFacade try { I stub = (I)UnicastRemoteObject.exportObject(proxy, 0); I stored = (I)myRemotes.putIfAbsent(implClass, stub); - return stored == null ? result : stored; + return stored == null ? stub : stored; } catch (RemoteException e) { Object raceResult = myRemotes.get(implClass); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java index df0e73be81c5..8a0b05240b37 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java @@ -3,10 +3,7 @@ package org.jetbrains.plugins.gradle.sync; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.LibraryOrderEntry; -import com.intellij.openapi.roots.ModuleOrderEntry; -import com.intellij.openapi.roots.OrderEntry; -import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.util.Ref; @@ -177,6 +174,21 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent { return null; } + @Nullable + public LibraryOrderEntry findIntellijLibraryDependency(@NotNull final String libraryName, + @NotNull ModifiableRootModel model) + { + for (OrderEntry entry : model.getOrderEntries()) { + if (entry instanceof LibraryOrderEntry) { + LibraryOrderEntry candidate = (LibraryOrderEntry)entry; + if (libraryName.equals(candidate.getLibraryName())) { + return candidate; + } + } + } + return null; + } + @Nullable public GradleLibrary findGradleLibrary(@NotNull final String libraryName) { final GradleProject project = myModel.getGradleProject(); @@ -268,6 +280,18 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent { } } return null; + } + @Nullable + public ModuleOrderEntry findIntellijModuleDependency(@NotNull GradleModuleDependency dependency, @NotNull ModifiableRootModel model) { + for (OrderEntry entry : model.getOrderEntries()) { + if (entry instanceof ModuleOrderEntry) { + ModuleOrderEntry candidate = (ModuleOrderEntry)entry; + if (dependency.getName().equals(candidate.getModuleName())) { + return candidate; + } + } + } + return null; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java index d39d0e20d981..6be6f4448fc2 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java @@ -74,7 +74,9 @@ public abstract class AbstractGradleTask implements GradleTask { catch (Throwable e) { setState(GradleTaskState.FAILED); myError.set(e); - LOG.warn(e); + if (myIntellijProject == null || !myIntellijProject.isDisposed()) { + LOG.warn(e); + } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java index 69b0ef1b7fcb..11e91135ec4f 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java @@ -503,23 +503,34 @@ public class GradleUtil { return INSTALLATION_MANAGER.getValue().getGradleHome(project) != null; } + public static void executeProjectChangeAction(@NotNull Project project, @NotNull Object entityToChange, @NotNull Runnable task) { executeProjectChangeAction(project, Collections.singleton(entityToChange), task); } - public static void executeProjectChangeAction(@NotNull Project project, @NotNull Iterable entitiesToChange, @NotNull Runnable task) { - final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); - for (Object e : entitiesToChange) { - publisher.onChangeStart(e); - } - try { - task.run(); - } - finally { - for (Object e : entitiesToChange) { - publisher.onChangeEnd(e); + public static void executeProjectChangeAction(@NotNull final Project project, @NotNull final Iterable entitiesToChange, @NotNull final Runnable task) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); + for (Object e : entitiesToChange) { + publisher.onChangeStart(e); + } + try { + task.run(); + } + finally { + for (Object e : entitiesToChange) { + publisher.onChangeEnd(e); + } + } + } + }); } - } + }); } private interface TaskUnderProgress {