mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-111342 Gradle: if root project is renamed by means of gradle, it is shown twice in tool window - as root project and as sub-project
1. Correctly update cached data at ExternalSystemFacadeManager on project rename; 2. Minor refactoring (method rename); 3. Drop obsolete data from 'local external system settings' on project rename; 4. Update external tool window project node representation on project rename;
This commit is contained in:
+10
-10
@@ -73,11 +73,11 @@ public abstract class AbstractExternalSystemLocalSettings {
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks current settings to drop all information related to external project which root config is located at the given path.
|
||||
* Asks current settings to drop all information related to external projects which root configs are located at the given paths.
|
||||
*
|
||||
* @param linkedProjectPathsToForget target root external project's path
|
||||
* @param linkedProjectPathsToForget target root external project paths
|
||||
*/
|
||||
public void forgetExternalProject(@NotNull Set<String> linkedProjectPathsToForget) {
|
||||
public void forgetExternalProjects(@NotNull Set<String> linkedProjectPathsToForget) {
|
||||
Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> projects = myAvailableProjects.get();
|
||||
for (Iterator<Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>>> it = projects.entrySet().iterator(); it.hasNext(); ) {
|
||||
Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>> entry = it.next();
|
||||
@@ -184,24 +184,24 @@ public abstract class AbstractExternalSystemLocalSettings {
|
||||
private void pruneOutdatedEntries() {
|
||||
ExternalSystemManager<?,?,?,?,?> manager = ExternalSystemApiUtil.getManager(myExternalSystemId);
|
||||
assert manager != null;
|
||||
Set<String> toForget = ContainerUtilRt.newHashSet();
|
||||
Set<String> pathsToForget = ContainerUtilRt.newHashSet();
|
||||
for (ExternalProjectPojo pojo : myAvailableProjects.get().keySet()) {
|
||||
toForget.add(pojo.getPath());
|
||||
pathsToForget.add(pojo.getPath());
|
||||
}
|
||||
for (String path : myAvailableTasks.get().keySet()) {
|
||||
toForget.add(path);
|
||||
pathsToForget.add(path);
|
||||
}
|
||||
for (ExternalTaskExecutionInfo taskInfo : myRecentTasks.get()) {
|
||||
toForget.add(taskInfo.getSettings().getExternalProjectPath());
|
||||
pathsToForget.add(taskInfo.getSettings().getExternalProjectPath());
|
||||
}
|
||||
|
||||
AbstractExternalSystemSettings<?, ?, ?> settings = manager.getSettingsProvider().fun(myProject);
|
||||
for (ExternalProjectSettings projectSettings : settings.getLinkedProjectsSettings()) {
|
||||
toForget.remove(projectSettings.getExternalProjectPath());
|
||||
pathsToForget.remove(projectSettings.getExternalProjectPath());
|
||||
}
|
||||
|
||||
if (!toForget.isEmpty()) {
|
||||
forgetExternalProject(toForget);
|
||||
if (!pathsToForget.isEmpty()) {
|
||||
forgetExternalProjects(pathsToForget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public class DetachExternalProjectAction extends AnAction implements DumbAware {
|
||||
recentTasksList.getModel().forgetTasksFrom(info.externalProject.getPath());
|
||||
}
|
||||
|
||||
info.localSettings.forgetExternalProject(Collections.singleton(info.externalProject.getPath()));
|
||||
info.localSettings.forgetExternalProjects(Collections.singleton(info.externalProject.getPath()));
|
||||
info.settings.unlinkExternalProject(info.externalProject.getPath());
|
||||
|
||||
// Process orphan modules.
|
||||
|
||||
+19
-7
@@ -45,6 +45,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ShutDownTracker;
|
||||
import com.intellij.psi.PsiBundle;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -244,8 +245,13 @@ public class ExternalSystemFacadeManager {
|
||||
key.getIdeProjectLocationHash(),
|
||||
key.getExternalSystemId(),
|
||||
key.getExternalProjectConfigPath());
|
||||
data.put(newKey, data.get(key));
|
||||
V value = data.get(key);
|
||||
data.put(newKey, value);
|
||||
data.remove(key);
|
||||
if (value instanceof Consumer) {
|
||||
//noinspection unchecked
|
||||
((Consumer)value).consume(newKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +271,7 @@ public class ExternalSystemFacadeManager {
|
||||
final RemoteExternalSystemFacade facade = myFacadeWrappers.get(key);
|
||||
if (facade == null) {
|
||||
final RemoteExternalSystemFacade newFacade = (RemoteExternalSystemFacade)Proxy.newProxyInstance(
|
||||
ExternalSystemFacadeManager.class.getClassLoader(), new Class[]{RemoteExternalSystemFacade.class}, new MyHandler(key)
|
||||
ExternalSystemFacadeManager.class.getClassLoader(), new Class[]{RemoteExternalSystemFacade.class, Consumer.class}, new MyHandler(key)
|
||||
);
|
||||
myFacadeWrappers.putIfAbsent(key, newFacade);
|
||||
}
|
||||
@@ -408,16 +414,22 @@ public class ExternalSystemFacadeManager {
|
||||
}
|
||||
|
||||
private class MyHandler implements InvocationHandler {
|
||||
|
||||
@NotNull private final IntegrationKey myKey;
|
||||
|
||||
@NotNull private final AtomicReference<IntegrationKey> myKey = new AtomicReference<IntegrationKey>();
|
||||
|
||||
MyHandler(@NotNull IntegrationKey key) {
|
||||
myKey = key;
|
||||
myKey.set(key);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
return doInvoke(myKey, findProject(myKey), method, args, REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER);
|
||||
if ("consume".equals(method.getName())) {
|
||||
myKey.set((IntegrationKey)args[0]);
|
||||
return null;
|
||||
}
|
||||
Project project = findProject(myKey.get());
|
||||
return doInvoke(myKey.get(), project, method, args, REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
-5
@@ -34,10 +34,7 @@ import com.intellij.util.containers.ContainerUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Ensures that all external system sub-projects are correctly represented at the external system tool window.
|
||||
@@ -82,8 +79,40 @@ public class ToolWindowModuleService extends AbstractToolWindowService<ModuleDat
|
||||
}
|
||||
|
||||
AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
|
||||
HashMap<ExternalProjectPojo,Collection<ExternalProjectPojo>> projects = ContainerUtilRt.newHashMap(settings.getAvailableProjects());
|
||||
Set<String> pathsToForget = detectRenamedProjects(data, settings.getAvailableProjects());
|
||||
if (!pathsToForget.isEmpty()) {
|
||||
settings.forgetExternalProjects(pathsToForget);
|
||||
}
|
||||
Map<ExternalProjectPojo,Collection<ExternalProjectPojo>> projects = ContainerUtilRt.newHashMap(settings.getAvailableProjects());
|
||||
projects.putAll(data);
|
||||
settings.setAvailableProjects(projects);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<String> detectRenamedProjects(@NotNull Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> currentInfo,
|
||||
@NotNull Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> oldInfo)
|
||||
{
|
||||
Map<String/* external config path */, String/* project name */> map = ContainerUtilRt.newHashMap();
|
||||
for (Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>> entry : currentInfo.entrySet()) {
|
||||
map.put(entry.getKey().getPath(), entry.getKey().getName());
|
||||
for (ExternalProjectPojo pojo : entry.getValue()) {
|
||||
map.put(pojo.getPath(), pojo.getName());
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> result = ContainerUtilRt.newHashSet();
|
||||
for (Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>> entry : oldInfo.entrySet()) {
|
||||
String newName = map.get(entry.getKey().getPath());
|
||||
if (newName != null && !newName.equals(entry.getKey().getName())) {
|
||||
result.add(entry.getKey().getPath());
|
||||
}
|
||||
for (ExternalProjectPojo pojo : entry.getValue()) {
|
||||
newName = map.get(pojo.getPath());
|
||||
if (newName != null && !newName.equals(pojo.getName())) {
|
||||
result.add(pojo.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -37,6 +37,10 @@ public class ExternalSystemNodeDescriptor<T> extends PresentableNodeDescriptor<T
|
||||
setIcon(icon);
|
||||
}
|
||||
|
||||
public void setName(@NotNull String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(PresentationData presentation) {
|
||||
presentation.setPresentableText(myName);
|
||||
|
||||
+12
-8
@@ -16,7 +16,6 @@
|
||||
package com.intellij.openapi.externalSystem.service.task.ui;
|
||||
|
||||
import com.intellij.execution.executors.DefaultRunExecutor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
|
||||
@@ -40,8 +39,6 @@ import java.util.*;
|
||||
*/
|
||||
public class ExternalSystemTasksTreeModel extends DefaultTreeModel {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + ExternalSystemTasksTreeModel.class.getName());
|
||||
|
||||
@NotNull private static final Comparator<TreeNode> NODE_COMPARATOR = new Comparator<TreeNode>() {
|
||||
@Override
|
||||
public int compare(TreeNode t1, TreeNode t2) {
|
||||
@@ -95,11 +92,18 @@ public class ExternalSystemTasksTreeModel extends DefaultTreeModel {
|
||||
// Remove outdated projects.
|
||||
for (int i = root.getChildCount() - 1; i >= 0; i--) {
|
||||
ExternalSystemNode<?> child = root.getChildAt(i);
|
||||
Object element = child.getDescriptor().getElement();
|
||||
if (element instanceof ExternalProjectPojo
|
||||
&& ((ExternalProjectPojo)element).getPath().equals(project.getPath()))
|
||||
{
|
||||
return (ExternalSystemNode<ExternalProjectPojo>)child;
|
||||
ExternalSystemNodeDescriptor<?> descriptor = child.getDescriptor();
|
||||
Object element = descriptor.getElement();
|
||||
if (element instanceof ExternalProjectPojo) {
|
||||
ExternalProjectPojo pojo = (ExternalProjectPojo)element;
|
||||
if (pojo.getPath().equals(project.getPath())) {
|
||||
if (!pojo.getName().equals(project.getName())) {
|
||||
pojo.setName(project.getName());
|
||||
descriptor.setName(project.getName());
|
||||
nodeChanged(child);
|
||||
}
|
||||
return (ExternalSystemNode<ExternalProjectPojo>)child;
|
||||
}
|
||||
}
|
||||
}
|
||||
ExternalProjectPojo element = new ExternalProjectPojo(project.getName(), project.getPath());
|
||||
|
||||
+5
-4
@@ -206,7 +206,7 @@ public class ExternalSystemUtil {
|
||||
ExternalProjectRefreshCallback callback = new ExternalProjectRefreshCallback() {
|
||||
|
||||
@NotNull
|
||||
private final Set<String> myExternalModuleNames = ContainerUtilRt.newHashSet();
|
||||
private final Set<String> myExternalModulePaths = ContainerUtilRt.newHashSet();
|
||||
|
||||
@Override
|
||||
public void onSuccess(@Nullable final DataNode<ProjectData> externalProject) {
|
||||
@@ -215,7 +215,7 @@ public class ExternalSystemUtil {
|
||||
}
|
||||
Collection<DataNode<ModuleData>> moduleNodes = ExternalSystemApiUtil.findAll(externalProject, ProjectKeys.MODULE);
|
||||
for (DataNode<ModuleData> node : moduleNodes) {
|
||||
myExternalModuleNames.add(node.getData().getName());
|
||||
myExternalModulePaths.add(node.getData().getLinkedExternalProjectPath());
|
||||
}
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(true, new Runnable() {
|
||||
@Override
|
||||
@@ -225,7 +225,7 @@ public class ExternalSystemUtil {
|
||||
public void run() {
|
||||
projectDataManager.importData(externalProject.getKey(), Collections.singleton(externalProject), project, true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
if (--counter[0] <= 0) {
|
||||
@@ -245,7 +245,8 @@ public class ExternalSystemUtil {
|
||||
|
||||
for (Module module : platformFacade.getModules(project)) {
|
||||
String s = module.getOptionValue(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY);
|
||||
if (externalSystemIdAsString.equals(s) && !myExternalModuleNames.contains(module.getName())) {
|
||||
String p = module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY);
|
||||
if (externalSystemIdAsString.equals(s) && !myExternalModulePaths.contains(p)) {
|
||||
orphanIdeModules.add(module);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-3
@@ -436,8 +436,9 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
|
||||
// Our aim is to make sub-project nodes contain corresponding TaskData nodes and add root project tasks to ProjectData node.
|
||||
// The later is achieved by composing all tasks from IdeaModule which corresponds to the IdeaProject plus all tasks
|
||||
// which are shared between all sub-projects.
|
||||
|
||||
final String rootProjectPath = rootProjectNode.getData().getLinkedExternalProjectPath();
|
||||
|
||||
ProjectData projectData = rootProjectNode.getData();
|
||||
final String rootProjectPath = projectData.getLinkedExternalProjectPath();
|
||||
Map<String/* module name */, Collection<TaskData>> tasksByModule = ContainerUtilRt.newHashMap();
|
||||
TObjectIntHashMap<Pair<String/* task name */, String /* task description */>> rootProjectTaskCandidates
|
||||
= new TObjectIntHashMap<Pair<String, String>>();
|
||||
@@ -487,7 +488,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
|
||||
|
||||
Collection<DataNode<ModuleData>> moduleNodes = ExternalSystemApiUtil.findAll(rootProjectNode, ProjectKeys.MODULE);
|
||||
for (DataNode<ModuleData> moduleNode : moduleNodes) {
|
||||
Collection<TaskData> tasks = tasksByModule.get(moduleNode.getData().getName());
|
||||
ModuleData moduleData = moduleNode.getData();
|
||||
if (rootProjectPath.equals(moduleData.getLinkedExternalProjectPath()) && !projectData.getName().equals(moduleData.getName())) {
|
||||
moduleData.setName(projectData.getName());
|
||||
}
|
||||
Collection<TaskData> tasks = tasksByModule.get(moduleData.getName());
|
||||
if (tasks != null && !tasks.isEmpty()) {
|
||||
for (TaskData task : tasks) {
|
||||
moduleNode.createChild(ProjectKeys.TASK, task);
|
||||
|
||||
Reference in New Issue
Block a user