diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataService.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataService.java index e6f9f63c5b01..1a67a1f91c8d 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataService.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataService.java @@ -57,6 +57,25 @@ public interface ProjectDataService { @NotNull Key getTargetDataKey(); + /** + * It's assumed that given data nodes present at the ide when this method returns. I.e. the method should behave as below for + * every of the given data nodes: + *
+   * 
    + *
  • there is an existing project entity for the given data node and it has the same state. Do nothing for it then;
  • + *
  • + * there is an existing project entity for the given data node but it has different state (e.g. a module dependency + * is configured as 'exported' at the ide but not at external system). Reset the state to the external system's one then; + *
  • + *
  • there is no corresponding project entity at the ide side. Create it then;
  • + *
+ *
+ * are created, updated or left as-is if they have the + * + * @param toImport + * @param project + * @param synchronous + */ void importData(@NotNull Collection> toImport, @NotNull Project project, boolean synchronous); void removeData(@NotNull Collection> toRemove, @NotNull Project project, boolean synchronous); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java index 1e17d29640b2..4b7bbbf2cc02 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java @@ -27,10 +27,7 @@ import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; import java.io.File; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author Denis Zhdanov @@ -40,6 +37,13 @@ import java.util.Set; public class LibraryDataService implements ProjectDataService { private static final Logger LOG = Logger.getInstance("#" + LibraryDataService.class.getName()); + @NotNull public static final NotNullFunction PATH_TO_FILE = new NotNullFunction() { + @NotNull + @Override + public File fun(String path) { + return new File(path); + } + }; @NotNull private final PlatformFacade myPlatformFacade; @NotNull private final ProjectStructureHelper myProjectStructureHelper; @@ -68,19 +72,19 @@ public class LibraryDataService implements ProjectDataService { } public void importLibrary(@NotNull final LibraryData toImport, @NotNull final Project project, boolean synchronous) { - Map> libraryFiles = new HashMap>(); + Map> libraryFiles = ContainerUtilRt.newHashMap(); for (LibraryPathType pathType : LibraryPathType.values()) { final Set paths = toImport.getPaths(pathType); if (paths.isEmpty()) { continue; } - libraryFiles.put(myLibraryPathTypeMapper.map(pathType), ContainerUtil.map(paths, new NotNullFunction() { - @NotNull - @Override - public File fun(String path) { - return new File(path); - } - })); + libraryFiles.put(myLibraryPathTypeMapper.map(pathType), ContainerUtil.map(paths, PATH_TO_FILE)); + } + + Library library = myProjectStructureHelper.findIdeLibrary(toImport, project); + if (library != null) { + syncPaths(toImport, library, project, synchronous); + return; } importLibrary(toImport.getName(), toImport.getOwner(), libraryFiles, project, synchronous); } @@ -186,13 +190,13 @@ public class LibraryDataService implements ProjectDataService { }); } - public void syncPaths(@NotNull LibraryData externalLibrary, + public void syncPaths(@NotNull final LibraryData externalLibrary, @NotNull final Library ideLibrary, @NotNull Project project, boolean synchronous) { - Set toRemove = ContainerUtilRt.newHashSet(); - Set toAdd = ContainerUtilRt.newHashSet(externalLibrary.getPaths(LibraryPathType.BINARY)); + final Set toRemove = ContainerUtilRt.newHashSet(); + final Set toAdd = ContainerUtilRt.newHashSet(externalLibrary.getPaths(LibraryPathType.BINARY)); for (VirtualFile ideFile : ideLibrary.getFiles(OrderRootType.CLASSES)) { String idePath = ExternalSystemApiUtil.getLocalFileSystemPath(ideFile); if (!toAdd.remove(idePath)) { @@ -202,6 +206,22 @@ public class LibraryDataService implements ProjectDataService { if (toRemove.isEmpty() && toAdd.isEmpty()) { return; } - // TODO den implement + ExternalSystemApiUtil.executeProjectChangeAction(project, externalLibrary.getOwner(), ideLibrary, synchronous, new Runnable() { + @Override + public void run() { + Library.ModifiableModel model = ideLibrary.getModifiableModel(); + try { + for (String path : toRemove) { + model.removeRoot(path, OrderRootType.CLASSES); + } + Map> roots = ContainerUtilRt.newHashMap(); + roots.put(OrderRootType.CLASSES, ContainerUtil.map(toAdd, PATH_TO_FILE)); + registerPaths(roots, model, externalLibrary.getName()); + } + finally { + model.commit(); + } + } + }); } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java index 94af73a0ad05..1f6cc95945b3 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; import java.util.Collection; +import java.util.Iterator; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -75,7 +76,11 @@ public class ModuleDataService implements ProjectDataService { Runnable task = new Runnable() { @Override public void run() { - removeExistingModulesConfigs(toImport, project); + final Collection> toCreate = filterExistingModules(toImport, project); + if (toCreate.isEmpty()) { + return; + } + removeExistingModulesConfigs(toCreate, project); Application application = ApplicationManager.getApplication(); final Map, Module> moduleMappings = ContainerUtilRt.newHashMap(); application.runWriteAction(new Runnable() { @@ -84,7 +89,7 @@ public class ModuleDataService implements ProjectDataService { final ModuleManager moduleManager = ModuleManager.getInstance(project); final ProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(ProjectEntityChangeListener.TOPIC); - for (DataNode module : toImport) { + for (DataNode module : toCreate) { publisher.onChangeStart(module, module.getData().getOwner()); try { importModule(moduleManager, module); @@ -143,6 +148,19 @@ public class ModuleDataService implements ProjectDataService { } } + @NotNull + private Collection> filterExistingModules(@NotNull Collection> modules, + @NotNull Project project) + { + Collection> result = ContainerUtilRt.newArrayList(); + for (DataNode node : modules) { + if (myProjectStructureHelper.findIdeModule(node.getData(), project) == null) { + result.add(node); + } + } + return result; + } + private void removeExistingModulesConfigs(@NotNull final Collection> nodes, @NotNull Project project) { if (nodes.isEmpty()) { return;