From 8561fe14066f6fed0b0a5a4e9353392a520fd174 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Fri, 24 Feb 2012 14:57:29 +0400 Subject: [PATCH] IDEA-76142: Gradle support - cannot update IDEA projects once one of build.gradle files changes Don't trigger 'refresh gradle project' on project structure changes performed by the gradle integration --- .../gradle/config/GradleConfigNotifier.java | 2 + .../importing/GradleLibraryImporter.java | 9 ++- .../GradleModuleDependencyImporter.java | 8 +++ .../importing/GradleModuleImporter.java | 58 +++++++++++-------- .../importing/GradleModulesImporter.java | 8 +++ .../GradleProjectEntityImportListener.java | 31 ++++++++++ 6 files changed, 92 insertions(+), 24 deletions(-) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectEntityImportListener.java diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifier.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifier.java index 21c42c9a8a22..977c5bef1d23 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifier.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifier.java @@ -5,6 +5,8 @@ import org.jetbrains.annotations.Nullable; /** * Defines callback for the gradle config structure change. + *

+ * Implementations of this interface are not obliged to be thread-safe. * * @author Denis Zhdanov * @since 1/17/12 1:02 PM diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLibraryImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLibraryImporter.java index ff319ba48600..97a21711e88c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLibraryImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLibraryImporter.java @@ -36,7 +36,14 @@ public class GradleLibraryImporter { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - doImportLibrary(library, project); + final GradleProjectEntityImportListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityImportListener.TOPIC); + publisher.onImportStart(library); + try { + doImportLibrary(library, project); + } + finally { + publisher.onImportEnd(library); + } } }); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleDependencyImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleDependencyImporter.java index 84c6009f7ef2..fbdf278848fd 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleDependencyImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleDependencyImporter.java @@ -123,12 +123,15 @@ public class GradleModuleDependencyImporter { // Register library dependencies. ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); + final GradleProjectEntityImportListener publisher + = module.getProject().getMessageBus().syncPublisher(GradleProjectEntityImportListener.TOPIC); try { for (GradleLibraryDependency dependency : dependencies) { final Library library = gradle2intellij.get(dependency.getTarget()); if (library == null) { continue; } + publisher.onImportStart(library); LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(library); orderEntry.setExported(dependency.isExported()); orderEntry.setScope(dependency.getScope()); @@ -136,6 +139,11 @@ public class GradleModuleDependencyImporter { } finally { moduleRootModel.commit(); + for (GradleLibraryDependency dependency : dependencies) { + if (dependency != null) { + publisher.onImportEnd(dependency); + } + } } } }); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleImporter.java index ef5ccd9b50e4..aadcd66faa85 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleImporter.java @@ -64,36 +64,48 @@ public class GradleModuleImporter { @Override public void run() { final ModuleManager moduleManager = ModuleManager.getInstance(project); + final GradleProjectEntityImportListener publisher + = project.getMessageBus().syncPublisher(GradleProjectEntityImportListener.TOPIC); for (GradleModule module : modules) { - final Module created = moduleManager.newModule(module.getModuleFilePath(), StdModuleTypes.JAVA); - - // Ensure that the dependencies are clear (used to be not clear when manually removing the module and importing it via gradle) - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(created); - final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); - RootPolicy visitor = new RootPolicy() { - @Override - public Object visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry, Object value) { - moduleRootModel.removeOrderEntry(libraryOrderEntry); - return value; - } - - @Override - public Object visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, Object value) { - moduleRootModel.removeOrderEntry(moduleOrderEntry); - return value; - } - }; + publisher.onImportStart(module); try { - for (OrderEntry orderEntry : moduleRootModel.getOrderEntries()) { - orderEntry.accept(visitor, null); - } + importModule(moduleManager, module); } finally { - moduleRootModel.commit(); + publisher.onImportEnd(module); } - moduleMappings.put(module, created); } } + + private void importModule(@NotNull ModuleManager moduleManager, @NotNull GradleModule module) { + final Module created = moduleManager.newModule(module.getModuleFilePath(), StdModuleTypes.JAVA); + + // Ensure that the dependencies are clear (used to be not clear when manually removing the module and importing it via gradle) + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(created); + final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); + RootPolicy visitor = new RootPolicy() { + @Override + public Object visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry, Object value) { + moduleRootModel.removeOrderEntry(libraryOrderEntry); + return value; + } + + @Override + public Object visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, Object value) { + moduleRootModel.removeOrderEntry(moduleOrderEntry); + return value; + } + }; + try { + for (OrderEntry orderEntry : moduleRootModel.getOrderEntries()) { + orderEntry.accept(visitor, null); + } + } + finally { + moduleRootModel.commit(); + } + moduleMappings.put(module, created); + } }); if (!recursive) { return; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java index 8269cd9682b8..c6edb9243c52 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java @@ -114,6 +114,11 @@ public class GradleModulesImporter { AccessToken writeLock = application.acquireWriteActionLock(getClass()); try { final List rootModels = new ArrayList(); + final GradleProjectEntityImportListener publisher = + intellijProject.getMessageBus().syncPublisher(GradleProjectEntityImportListener.TOPIC); + for (GradleModule module : modules) { + publisher.onImportStart(module); + } try { Map moduleMappings = doImportModules(modules, model, rootModels); result.putAll(moduleMappings); @@ -127,6 +132,9 @@ public class GradleModulesImporter { ProjectRootManager projectRootManager = ProjectRootManager.getInstance(intellijProject); ModifiableRootModel[] modelsAsArray = rootModels.toArray(new ModifiableRootModel[rootModels.size()]); projectRootManager.multiCommit(model, modelsAsArray); + for (GradleModule module : modules) { + publisher.onImportEnd(module); + } } } finally { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectEntityImportListener.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectEntityImportListener.java new file mode 100644 index 000000000000..98b231b83f3c --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectEntityImportListener.java @@ -0,0 +1,31 @@ +package org.jetbrains.plugins.gradle.importing; + +import com.intellij.util.messages.Topic; +import org.jetbrains.annotations.NotNull; + +/** + * Defines contract for the callback to be notified on project structure changes triggered by the gradle integrations. + *

+ * Implementations of this interface are not obliged to be thread-safe. + * + * @author Denis Zhdanov + * @since 2/24/12 1:05 PM + */ +public interface GradleProjectEntityImportListener { + + Topic TOPIC = Topic.create("Gradle config", GradleProjectEntityImportListener.class); + + /** + * Is called before the given entity is imported. + * + * @param entity target entity being imported + */ + void onImportStart(@NotNull Object entity); + + /** + * Is called after the given entity has been imported. + * + * @param entity target entity that has been imported + */ + void onImportEnd(@NotNull Object entity); +}