mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-108633 Gradle: Provide 'auto-import' feature
'Auto-import' api and infrastructure is provided
This commit is contained in:
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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 com.intellij.openapi.externalSystem;
|
||||
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* External system integration provides 'auto-import' feature, i.e. it listens for external system config files changes
|
||||
* and automatically runs external project refresh and sync.
|
||||
* <p/>
|
||||
* Only {@link AbstractExternalSystemSettings#getLinkedProjectsSettings() registered project's}
|
||||
* {@link ExternalProjectSettings#getExternalProjectPath() config files} are processed by default. However, there is a possible case
|
||||
* that there are other auxiliary config files/directories which modification should trigger external project refresh. This interface
|
||||
* is supposed to handle that situation, i.e. any {@link ExternalSystemManager external system implementation} which requires
|
||||
* the functionality described above should implement this interface.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 6/7/13 6:44 PM
|
||||
*/
|
||||
public interface ExternalSystemAutoImportAware {
|
||||
|
||||
/**
|
||||
* This method serves to check if particular file/dir change should trigger external project refresh.
|
||||
* <p/>
|
||||
* <b>Note:</b> there is no need to handle here {@link ExternalProjectSettings#getExternalProjectPath() external project config files}
|
||||
* known to the ide as that functionality is built-in. Only auxiliary files should be processed.
|
||||
*
|
||||
* @param changedFileOrDirPath changed file/dir path
|
||||
* @return <code>null</code> if target change should not trigger external project refresh;
|
||||
* path to config file of an external project which should be refreshed
|
||||
*/
|
||||
@Nullable
|
||||
String getAffectedExternalProjectPath(@NotNull String changedFileOrDirPath);
|
||||
}
|
||||
+4
@@ -186,6 +186,10 @@ public class ExternalSystemApiUtil {
|
||||
return MANAGERS.getValue().get(externalSystemId);
|
||||
}
|
||||
|
||||
public static Collection<ExternalSystemManager<?, ?, ?, ?, ?>> getAllManagers() {
|
||||
return MANAGERS.getValue().values();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<Key<?>, List<DataNode<?>>> group(@NotNull Collection<DataNode<?>> nodes) {
|
||||
if (nodes.isEmpty()) {
|
||||
|
||||
+5
-3
@@ -34,9 +34,11 @@ public class ExternalSystemConstants {
|
||||
@NonNls @NotNull public static final String TOOL_WINDOW_PLACE = "ExternalSystem.ToolWindow";
|
||||
@NonNls @NotNull public static final String TREE_PLACE = "ExternalSystem.Tree";
|
||||
|
||||
public static final boolean VERBOSE_PROCESSING = SystemProperties.getBooleanProperty("external.system.verbose.processing", false);
|
||||
public static final int RECENT_TASKS_NUMBER = SystemProperties.getIntProperty("external.system.recent.tasks.number", 5);
|
||||
public static final char PATH_SEPARATOR = '/';
|
||||
public static final boolean VERBOSE_PROCESSING = SystemProperties.getBooleanProperty("external.system.verbose.processing", false);
|
||||
public static final int RECENT_TASKS_NUMBER = SystemProperties.getIntProperty("external.system.recent.tasks.number", 5);
|
||||
public static final int AUTO_IMPORT_DELAY_MILLIS = SystemProperties.getIntProperty("external.system.auto.import.delay.ms", 3000);
|
||||
|
||||
public static final char PATH_SEPARATOR = '/';
|
||||
|
||||
// Order.
|
||||
public static final int BUILTIN_SERVICE_ORDER = 42;
|
||||
|
||||
+2
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.externalSystem.service;
|
||||
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.autoimport.ExternalSystemAutoImporter;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -43,6 +44,7 @@ public class ExternalSystemStartupActivity implements StartupActivity {
|
||||
ExternalSystemUtil.refreshProjects(project, manager.getSystemId());
|
||||
}
|
||||
}
|
||||
ExternalSystemAutoImporter.letTheMagicBegin(project);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@ import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver;
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -31,9 +31,9 @@ public interface ExternalProjectRefreshCallback {
|
||||
|
||||
/**
|
||||
* Is expected to be called when
|
||||
* {@link ExternalSystemProjectResolver#resolveProjectInfo(ExternalSystemTaskId, String, boolean, ExternalSystemExecutionSettings)}
|
||||
* {@link ExternalSystemProjectResolver#resolveProjectInfo(ExternalSystemTaskId, String, boolean, ExternalSystemExecutionSettings, ExternalSystemTaskNotificationListener)}
|
||||
* returns without exception.
|
||||
*
|
||||
*
|
||||
* @param externalProject target external project (if available)
|
||||
*/
|
||||
void onSuccess(@Nullable DataNode<ProjectData> externalProject);
|
||||
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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 com.intellij.openapi.externalSystem.service.project.autoimport;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.event.DocumentListener;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemAutoImportAware;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 6/7/13 6:38 PM
|
||||
*/
|
||||
public class ExternalSystemAutoImporter implements BulkFileListener, DocumentListener {
|
||||
|
||||
@NotNull private final ConcurrentMap<ProjectSystemId, Set<String /* external project path */>> myFilesToRefresh
|
||||
= ContainerUtil.newConcurrentMap();
|
||||
|
||||
@NotNull private final Alarm myVfsAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
|
||||
@NotNull private final ReadWriteLock myVfsLock = new ReentrantReadWriteLock();
|
||||
|
||||
@NotNull private final Set<Document> myDocumentsToSave = ContainerUtilRt.newHashSet();
|
||||
@NotNull private final Alarm myDocumentAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
|
||||
@NotNull private final ReadWriteLock myDocumentLock = new ReentrantReadWriteLock();
|
||||
|
||||
@NotNull private final Runnable myFilesRequest = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
refreshFilesIfNecessary();
|
||||
}
|
||||
};
|
||||
@NotNull private final Runnable myDocumentsSaveRequest = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
saveDocumentsIfNecessary();
|
||||
}
|
||||
};
|
||||
@NotNull private final ExternalProjectRefreshCallback myRefreshCallback = new ExternalProjectRefreshCallback() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable DataNode<ProjectData> externalProject) {
|
||||
if (externalProject != null) {
|
||||
myProjectDataManager.importData(externalProject.getKey(), Collections.singleton(externalProject), myProject, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) {
|
||||
// Do nothing.
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final ProjectDataManager myProjectDataManager;
|
||||
|
||||
@NotNull private final MyEntry[] myAutoImportAware;
|
||||
|
||||
public ExternalSystemAutoImporter(@NotNull Project project,
|
||||
@NotNull ProjectDataManager projectDataManager,
|
||||
@NotNull MyEntry[] autoImportAware)
|
||||
{
|
||||
myProject = project;
|
||||
myProjectDataManager = projectDataManager;
|
||||
myAutoImportAware = autoImportAware;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void letTheMagicBegin(@NotNull Project project) {
|
||||
List<MyEntry> autoImportAware = ContainerUtilRt.newArrayList();
|
||||
Collection<ExternalSystemManager<?, ?, ?, ?, ?>> managers = ExternalSystemApiUtil.getAllManagers();
|
||||
for (ExternalSystemManager<?, ?, ?, ?, ?> manager : managers) {
|
||||
AbstractExternalSystemSettings<?, ?> systemSettings = manager.getSettingsProvider().fun(project);
|
||||
ExternalSystemAutoImportAware defaultImportAware = createDefault(systemSettings);
|
||||
final ExternalSystemAutoImportAware aware;
|
||||
if (manager instanceof ExternalSystemAutoImportAware) {
|
||||
aware = combine(defaultImportAware, (ExternalSystemAutoImportAware)manager);
|
||||
}
|
||||
else {
|
||||
aware = defaultImportAware;
|
||||
}
|
||||
autoImportAware.add(new MyEntry(manager.getSystemId(), systemSettings, aware));
|
||||
}
|
||||
|
||||
MyEntry[] entries = autoImportAware.toArray(new MyEntry[autoImportAware.size()]);
|
||||
ExternalSystemAutoImporter autoImporter = new ExternalSystemAutoImporter(
|
||||
project,
|
||||
ServiceManager.getService(ProjectDataManager.class),
|
||||
entries
|
||||
);
|
||||
final MessageBus messageBus = project.getMessageBus();
|
||||
messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, autoImporter);
|
||||
|
||||
EditorFactory.getInstance().getEventMulticaster().addDocumentListener(autoImporter, project);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ExternalSystemAutoImportAware combine(@NotNull final ExternalSystemAutoImportAware aware1,
|
||||
@NotNull final ExternalSystemAutoImportAware aware2)
|
||||
{
|
||||
return new ExternalSystemAutoImportAware() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getAffectedExternalProjectPath(@NotNull String changedFileOrDirPath) {
|
||||
String projectPath = aware1.getAffectedExternalProjectPath(changedFileOrDirPath);
|
||||
return projectPath == null ? aware2.getAffectedExternalProjectPath(changedFileOrDirPath) : projectPath;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ExternalSystemAutoImportAware createDefault(@NotNull final AbstractExternalSystemSettings<?, ?> systemSettings) {
|
||||
return new ExternalSystemAutoImportAware() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getAffectedExternalProjectPath(@NotNull String changedFileOrDirPath) {
|
||||
return systemSettings.getLinkedProjectSettings(changedFileOrDirPath) == null ? null : changedFileOrDirPath;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeDocumentChange(DocumentEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent event) {
|
||||
Document document = event.getDocument();
|
||||
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
|
||||
VirtualFile file = fileDocumentManager.getFile(document);
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String path = ExternalSystemApiUtil.getLocalFileSystemPath(file);
|
||||
for (MyEntry entry : myAutoImportAware) {
|
||||
if (entry.aware.getAffectedExternalProjectPath(path) != null) {
|
||||
// Document save triggers VFS event but FileDocumentManager might be registered after the current listener, that's why
|
||||
// call to 'saveDocument()' might not produce the desired effect. That's why we reschedule document save if necessary.
|
||||
scheduleDocumentSave(document);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleDocumentSave(@NotNull Document document) {
|
||||
Lock lock = myDocumentLock.readLock();
|
||||
lock.lock();
|
||||
try {
|
||||
myDocumentsToSave.add(document);
|
||||
if (myDocumentAlarm.getActiveRequestCount() <= 0) {
|
||||
myDocumentAlarm.addRequest(myDocumentsSaveRequest, 100);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveDocumentsIfNecessary() {
|
||||
final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
|
||||
Lock lock = myDocumentLock.writeLock();
|
||||
Set<Document> toKeep = ContainerUtilRt.newHashSet();
|
||||
final Set<Document> toSave = ContainerUtilRt.newHashSet();
|
||||
lock.lock();
|
||||
try {
|
||||
myDocumentAlarm.cancelAllRequests();
|
||||
for (Document document : myDocumentsToSave) {
|
||||
if (fileDocumentManager.isDocumentUnsaved(document)) {
|
||||
toSave.add(document);
|
||||
}
|
||||
else {
|
||||
toKeep.add(document);
|
||||
}
|
||||
}
|
||||
myDocumentsToSave.clear();
|
||||
if (!toSave.isEmpty()) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Document document : toSave) {
|
||||
fileDocumentManager.saveDocument(document);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!toKeep.isEmpty()) {
|
||||
myDocumentsToSave.addAll(toKeep);
|
||||
myDocumentAlarm.addRequest(myDocumentsSaveRequest, 100);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void before(@NotNull List<? extends VFileEvent> events) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void after(@NotNull List<? extends VFileEvent> events) {
|
||||
boolean scheduleRefresh = false;
|
||||
for (VFileEvent event : events) {
|
||||
String changedPath = event.getPath();
|
||||
for (MyEntry entry : myAutoImportAware) {
|
||||
String projectPath = entry.aware.getAffectedExternalProjectPath(changedPath);
|
||||
if (projectPath == null) {
|
||||
continue;
|
||||
}
|
||||
ExternalProjectSettings projectSettings = entry.systemSettings.getLinkedProjectSettings(projectPath);
|
||||
if (projectSettings != null && projectSettings.isUseAutoImport()) {
|
||||
addPath(entry.externalSystemId, projectPath);
|
||||
scheduleRefresh = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scheduleRefresh) {
|
||||
myVfsAlarm.cancelAllRequests();
|
||||
myVfsAlarm.addRequest(myFilesRequest, ExternalSystemConstants.AUTO_IMPORT_DELAY_MILLIS);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPath(@NotNull ProjectSystemId externalSystemId, @NotNull String path) {
|
||||
Lock lock = myVfsLock.readLock();
|
||||
lock.lock();
|
||||
try {
|
||||
Set<String> paths = myFilesToRefresh.get(externalSystemId);
|
||||
while (paths == null) {
|
||||
myFilesToRefresh.putIfAbsent(externalSystemId, ContainerUtilRt.<String>newHashSet());
|
||||
paths = myFilesToRefresh.get(externalSystemId);
|
||||
}
|
||||
paths.add(path);
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshFilesIfNecessary() {
|
||||
if (myFilesToRefresh.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<ProjectSystemId, Set<String>> copy = ContainerUtilRt.newHashMap();
|
||||
Lock fileLock = myVfsLock.writeLock();
|
||||
fileLock.lock();
|
||||
try {
|
||||
copy.putAll(myFilesToRefresh);
|
||||
myFilesToRefresh.clear();
|
||||
}
|
||||
finally {
|
||||
fileLock.unlock();
|
||||
}
|
||||
|
||||
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
|
||||
LocalFileSystem fileSystem = LocalFileSystem.getInstance();
|
||||
Lock documentLock = myDocumentLock.writeLock();
|
||||
documentLock.lock();
|
||||
try {
|
||||
for (Set<String> paths : copy.values()) {
|
||||
for (String path : paths) {
|
||||
VirtualFile file = fileSystem.findFileByPath(path);
|
||||
if (file != null) {
|
||||
Document document = fileDocumentManager.getCachedDocument(file);
|
||||
if (document != null) {
|
||||
myDocumentsToSave.remove(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
documentLock.unlock();
|
||||
}
|
||||
|
||||
for (Map.Entry<ProjectSystemId, Set<String>> entry : copy.entrySet()) {
|
||||
for (String path : entry.getValue()) {
|
||||
ExternalSystemUtil.refreshProject(myProject, entry.getKey(), path, myRefreshCallback, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyEntry {
|
||||
|
||||
@NotNull public final ProjectSystemId externalSystemId;
|
||||
@NotNull public final AbstractExternalSystemSettings<?, ?> systemSettings;
|
||||
@NotNull public final ExternalSystemAutoImportAware aware;
|
||||
|
||||
MyEntry(@NotNull ProjectSystemId externalSystemId,
|
||||
@NotNull AbstractExternalSystemSettings<?, ?> systemSettings,
|
||||
@NotNull ExternalSystemAutoImportAware aware)
|
||||
{
|
||||
this.externalSystemId = externalSystemId;
|
||||
this.systemSettings = systemSettings;
|
||||
this.aware = aware;
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-1
@@ -33,6 +33,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderEntry;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.util.BooleanFunction;
|
||||
@@ -133,12 +134,24 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService<
|
||||
myLibraryManager.importData(librariesToImport, module.getProject(), synchronous);
|
||||
}
|
||||
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
Map<String /* library name */, LibraryOrderEntry> toRemove = ContainerUtilRt.newHashMap();
|
||||
for (OrderEntry entry : moduleRootManager.getOrderEntries()) {
|
||||
if (entry instanceof LibraryOrderEntry) {
|
||||
LibraryOrderEntry e = (LibraryOrderEntry)entry;
|
||||
String libraryName = e.getLibraryName();
|
||||
if (libraryName != null) {
|
||||
toRemove.put(libraryName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (DataNode<LibraryDependencyData> dependencyNode : nodesToImport) {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
|
||||
try {
|
||||
libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject());
|
||||
final LibraryDependencyData dependencyData = dependencyNode.getData();
|
||||
toRemove.remove(dependencyData.getName());
|
||||
final Library library = libraryTable.getLibraryByName(dependencyData.getName());
|
||||
if (library == null) {
|
||||
assert false;
|
||||
@@ -161,6 +174,10 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService<
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
}
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
removeData(toRemove.values(), module, synchronous);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+15
@@ -31,7 +31,9 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleOrderEntry;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderEntry;
|
||||
import com.intellij.util.BooleanFunction;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -92,10 +94,19 @@ public class ModuleDependencyDataService extends AbstractDependencyDataService<M
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
Map<String /* dependency module name */, ModuleOrderEntry> toRemove = ContainerUtilRt.newHashMap();
|
||||
for (OrderEntry entry : moduleRootManager.getOrderEntries()) {
|
||||
if (entry instanceof ModuleOrderEntry) {
|
||||
ModuleOrderEntry e = (ModuleOrderEntry)entry;
|
||||
toRemove.put(e.getModuleName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
|
||||
try {
|
||||
for (DataNode<ModuleDependencyData> dependencyNode : toImport) {
|
||||
final ModuleDependencyData dependencyData = dependencyNode.getData();
|
||||
toRemove.remove(dependencyData.getName());
|
||||
final String moduleName = dependencyData.getName();
|
||||
Module ideDependencyModule = myProjectStructureHelper.findIdeModule(moduleName, module.getProject());
|
||||
if (ideDependencyModule == null) {
|
||||
@@ -135,6 +146,10 @@ public class ModuleDependencyDataService extends AbstractDependencyDataService<M
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
removeData(toRemove.values(), module, synchronous);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user