ProjectModelModificationService: allow adding library to several modules at once...
authornik <Nikolay.Chashnikov@jetbrains.com>
Fri, 7 Aug 2015 14:28:31 +0000 (17:28 +0300)
committernik <Nikolay.Chashnikov@jetbrains.com>
Fri, 7 Aug 2015 14:33:02 +0000 (17:33 +0300)
java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java
java/java-impl/src/com/intellij/openapi/roots/ProjectModelModificationService.java
java/java-impl/src/com/intellij/openapi/roots/ProjectModelModifier.java
java/java-impl/src/com/intellij/openapi/roots/impl/IdeaProjectModelModifier.java
java/java-impl/src/com/intellij/openapi/roots/impl/ProjectModelModificationServiceImpl.java
resources/src/META-INF/IdeaPlugin.xml

index 9e0ce12298e16c3e0bd98249a28870f569755c4b..b0bc31ffdd6d683b08bae56bcd15e325e577df89 100644 (file)
@@ -21,7 +21,7 @@ import com.intellij.analysis.BaseAnalysisAction;
 import com.intellij.analysis.BaseAnalysisActionDialog;
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.NullableNotNullManager;
-import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
+import com.intellij.codeInsight.daemon.impl.quickfix.JetBrainsAnnotationsExternalLibraryResolver;
 import com.intellij.history.LocalHistory;
 import com.intellij.history.LocalHistoryAction;
 import com.intellij.ide.util.PropertiesComponent;
@@ -35,7 +35,9 @@ import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectUtil;
+import com.intellij.openapi.roots.DependencyScope;
 import com.intellij.openapi.roots.ModuleRootModificationUtil;
+import com.intellij.openapi.roots.ProjectModelModificationService;
 import com.intellij.openapi.roots.libraries.Library;
 import com.intellij.openapi.roots.libraries.LibraryUtil;
 import com.intellij.openapi.ui.Messages;
@@ -179,18 +181,10 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
                                              "It is possible to configure custom JAR\nin e.g. Constant Conditions & Exceptions inspection or use JetBrains annotations available in installation. " +
                                              "\nIntelliJ IDEA nullity annotations are freely usable and redistributable under the Apache 2.0 license.\nWould you like to do it now?",
                                     title, Messages.getErrorIcon()) == Messages.OK) {
-      final List<String> paths = OrderEntryFix.locateAnnotationsJars(modulesWithoutAnnotations.iterator().next());
-      if (!paths.isEmpty()) {
-        new WriteCommandAction(project) {
-          @Override
-          protected void run(@NotNull final Result result) throws Throwable {
-            for (Module module : modulesWithoutAnnotations) {
-              OrderEntryFix.addJarsToRoots(paths, null, module, null);
-            }
-          }
-        }.execute();
-        return true;
-      }
+      Module firstModule = modulesWithoutAnnotations.iterator().next();
+      ProjectModelModificationService.getInstance(project).addDependency(modulesWithoutAnnotations, JetBrainsAnnotationsExternalLibraryResolver.getAnnotationsLibraryDescriptor(firstModule),
+                                                                         DependencyScope.COMPILE);
+      return true;
     }
     return false;
   }
index a148c4ed88ea78818b4cb2779f87f2ce732384cb..1a5e335f53333a8b43db846523a7d26edb1dcbde 100644 (file)
@@ -20,6 +20,9 @@ import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Collection;
+import java.util.Collections;
+
 /**
  * @author nik
  */
@@ -34,6 +37,14 @@ public abstract class ProjectModelModificationService {
 
   public abstract void addDependency(@NotNull Module from, @NotNull Module to, @NotNull DependencyScope scope);
 
-  public abstract void addDependency(@NotNull Module from, @NotNull ExternalLibraryDescriptor libraryDescriptor,
+  public void addDependency(@NotNull Module from, @NotNull ExternalLibraryDescriptor libraryDescriptor) {
+    addDependency(from, libraryDescriptor, DependencyScope.COMPILE);
+  }
+
+  public void addDependency(Module from, ExternalLibraryDescriptor descriptor, DependencyScope scope) {
+    addDependency(Collections.singletonList(from), descriptor, scope);
+  }
+
+  public abstract void addDependency(@NotNull Collection<Module> from, @NotNull ExternalLibraryDescriptor libraryDescriptor,
                                      @NotNull DependencyScope scope);
 }
index 98cb69960e2ce0a5d83280b2464eb1672409d8d7..9933040a91e7fe8018f540ef78ba48a33d599d90 100644 (file)
@@ -19,6 +19,8 @@ import com.intellij.openapi.extensions.ExtensionPointName;
 import com.intellij.openapi.module.Module;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Collection;
+
 /**
  * @author nik
  */
@@ -27,7 +29,7 @@ public abstract class ProjectModelModifier {
 
   public abstract boolean addModuleDependency(@NotNull Module from, @NotNull Module to, @NotNull DependencyScope scope);
 
-  public abstract boolean addExternalLibraryDependency(@NotNull Module module,
+  public abstract boolean addExternalLibraryDependency(@NotNull Collection<Module> modules,
                                                        @NotNull ExternalLibraryDescriptor descriptor,
                                                        @NotNull DependencyScope scope);
 }
index 71cc920e3ce64c6ace2c26e9062302048a234dc5..7653cedd7dca8d0d4986423776f83be5df28992d 100644 (file)
@@ -17,13 +17,19 @@ package com.intellij.openapi.roots.impl;
 
 import com.intellij.codeInsight.daemon.impl.quickfix.LocateLibraryDialog;
 import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
-import com.intellij.openapi.roots.ExternalLibraryDescriptor;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.module.Module;
-import com.intellij.openapi.roots.DependencyScope;
-import com.intellij.openapi.roots.ModuleRootModificationUtil;
-import com.intellij.openapi.roots.ProjectModelModifier;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
+import com.intellij.openapi.roots.libraries.LibraryUtil;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
@@ -31,6 +37,13 @@ import java.util.List;
  * @author nik
  */
 public class IdeaProjectModelModifier extends ProjectModelModifier {
+  private static final Logger LOG = Logger.getInstance(IdeaProjectModelModifier.class);
+  private final Project myProject;
+
+  public IdeaProjectModelModifier(Project project) {
+    myProject = project;
+  }
+
   @Override
   public boolean addModuleDependency(@NotNull Module from, @NotNull Module to, @NotNull DependencyScope scope) {
     ModuleRootModificationUtil.addDependency(from, to, scope, false);
@@ -38,16 +51,36 @@ public class IdeaProjectModelModifier extends ProjectModelModifier {
   }
 
   @Override
-  public boolean addExternalLibraryDependency(@NotNull Module module,
-                                              @NotNull ExternalLibraryDescriptor descriptor,
-                                              @NotNull DependencyScope scope) {
+  public boolean addExternalLibraryDependency(@NotNull final Collection<Module> modules,
+                                              @NotNull final ExternalLibraryDescriptor descriptor,
+                                              @NotNull final DependencyScope scope) {
     List<String> defaultRoots = descriptor.getLibraryClassesRoots();
-    LocateLibraryDialog dialog = new LocateLibraryDialog(module, defaultRoots, descriptor.getPresentableName());
+    Module firstModule = ContainerUtil.getFirstItem(modules);
+    LOG.assertTrue(firstModule != null);
+    LocateLibraryDialog dialog = new LocateLibraryDialog(firstModule, defaultRoots, descriptor.getPresentableName());
     List<String> classesRoots = dialog.showAndGetResult();
     if (!classesRoots.isEmpty()) {
       String libraryName = classesRoots.size() > 1 ? descriptor.getPresentableName() : null;
-      List<String> urls = OrderEntryFix.refreshAndConvertToUrls(classesRoots);
-      ModuleRootModificationUtil.addModuleLibrary(module, libraryName, urls, Collections.<String>emptyList(), scope);
+      final List<String> urls = OrderEntryFix.refreshAndConvertToUrls(classesRoots);
+      if (modules.size() == 1) {
+        ModuleRootModificationUtil.addModuleLibrary(firstModule, libraryName, urls, Collections.<String>emptyList(), scope);
+      }
+      else {
+        new WriteAction() {
+          protected void run(@NotNull Result result) {
+            Library library =
+              LibraryUtil.createLibrary(LibraryTablesRegistrar.getInstance().getLibraryTable(myProject), descriptor.getPresentableName());
+            Library.ModifiableModel model = library.getModifiableModel();
+            for (String url : urls) {
+              model.addRoot(url, OrderRootType.CLASSES);
+            }
+            model.commit();
+            for (Module module : modules) {
+              ModuleRootModificationUtil.addDependency(module, library, scope, false);
+            }
+          }
+        }.execute();
+      }
     }
     return true;
   }
index 70d7deb86234d26aad0cd1584bc9781272c7c2b6..962d2bceb521b276be75307a583ec7e907f35120 100644 (file)
  */
 package com.intellij.openapi.roots.impl;
 
-import com.intellij.openapi.roots.ExternalLibraryDescriptor;
 import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.DependencyScope;
+import com.intellij.openapi.roots.ExternalLibraryDescriptor;
 import com.intellij.openapi.roots.ProjectModelModificationService;
 import com.intellij.openapi.roots.ProjectModelModifier;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Collection;
+
 /**
  * @author nik
  */
 public class ProjectModelModificationServiceImpl extends ProjectModelModificationService {
+  private final Project myProject;
+
+  public ProjectModelModificationServiceImpl(Project project) {
+    myProject = project;
+  }
+
   @Override
   public void addDependency(@NotNull Module from, @NotNull Module to, @NotNull DependencyScope scope) {
     for (ProjectModelModifier modifier : getModelModifiers()) {
@@ -36,7 +45,7 @@ public class ProjectModelModificationServiceImpl extends ProjectModelModificatio
   }
 
   @Override
-  public void addDependency(@NotNull Module from, @NotNull ExternalLibraryDescriptor libraryDescriptor, @NotNull DependencyScope scope) {
+  public void addDependency(@NotNull Collection<Module> from, @NotNull ExternalLibraryDescriptor libraryDescriptor, @NotNull DependencyScope scope) {
     for (ProjectModelModifier modifier : getModelModifiers()) {
       if (modifier.addExternalLibraryDependency(from, libraryDescriptor, scope)) {
         return;
@@ -45,7 +54,7 @@ public class ProjectModelModificationServiceImpl extends ProjectModelModificatio
   }
 
   @NotNull
-  private static ProjectModelModifier[] getModelModifiers() {
-    return ProjectModelModifier.EP_NAME.getExtensions();
+  private ProjectModelModifier[] getModelModifiers() {
+    return ProjectModelModifier.EP_NAME.getExtensions(myProject);
   }
 }
index 3c25099049365cbdb9fc48750026d70df777b6ed..5f6b1a4d0341fa9a52ce22b9fda349591308fb21 100644 (file)
     <extensionPoint name="getterSetterProvider" interface="com.intellij.codeInsight.generation.GetterSetterPrototypeProvider"/>
 
     <extensionPoint name="library.dependencyScopeSuggester" interface="com.intellij.openapi.roots.LibraryDependencyScopeSuggester"/>
-    <extensionPoint name="projectModelModifier" interface="com.intellij.openapi.roots.ProjectModelModifier"/>
+    <extensionPoint name="projectModelModifier" interface="com.intellij.openapi.roots.ProjectModelModifier"
+                    area="IDEA_PROJECT"/>
 
     <extensionPoint name="refactoring.safeDelete.JavaSafeDeleteDelegate" beanClass="com.intellij.lang.LanguageExtensionPoint">
       <with attribute="implementationClass" implements="com.intellij.refactoring.safeDelete.JavaSafeDeleteDelegate"/>