simplify GTDUCollector a bit more
[idea/community.git] / platform / lang-impl / src / com / intellij / ide / projectView / impl / ModuleGroup.java
1 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2
3 package com.intellij.ide.projectView.impl;
4
5 import com.intellij.openapi.actionSystem.DataKey;
6 import com.intellij.openapi.module.Module;
7 import com.intellij.openapi.module.ModuleGrouper;
8 import com.intellij.openapi.project.Project;
9 import com.intellij.openapi.util.NlsSafe;
10 import com.intellij.openapi.util.text.StringUtil;
11 import com.intellij.util.ArrayUtilRt;
12 import com.intellij.util.containers.ContainerUtil;
13 import gnu.trove.THashSet;
14 import org.jetbrains.annotations.NotNull;
15
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.List;
19 import java.util.Set;
20
21 public class ModuleGroup {
22   public static final DataKey<ModuleGroup[]> ARRAY_DATA_KEY = DataKey.create("moduleGroup.array");
23   private final List<String> myGroupPath;
24
25   public ModuleGroup(@NotNull List<String> groupPath) {
26     myGroupPath = groupPath;
27   }
28
29   @Override
30   public boolean equals(Object o) {
31     if (this == o) return true;
32     if (!(o instanceof ModuleGroup)) return false;
33
34     return myGroupPath.equals(((ModuleGroup)o).myGroupPath);
35   }
36
37   @Override
38   public int hashCode() {
39     return myGroupPath.hashCode();
40   }
41
42   public String @NotNull [] getGroupPath() {
43     return ArrayUtilRt.toStringArray(myGroupPath);
44   }
45
46   @NotNull
47   public List<String> getGroupPathList() {
48     return myGroupPath;
49   }
50
51   @NotNull
52   public Collection<Module> modulesInGroup(@NotNull Project project, boolean recursively) {
53     return modulesInGroup(ModuleGrouper.instanceFor(project), recursively);
54   }
55
56   /**
57    * Returns modules in this group (without modules in sub-groups) using cache built for default project grouper.
58    */
59   @NotNull
60   public Collection<Module> modulesInGroup(@NotNull Project project) {
61     return ModuleGroupsTree.getModuleGroupTree(project).getModulesInGroup(this);
62   }
63
64   @NotNull
65   public Collection<Module> modulesInGroup(@NotNull ModuleGrouper grouper, boolean recursively) {
66     List<Module> result = new ArrayList<>();
67     Set<List<String>> moduleAsGroupsPaths = ContainerUtil.map2Set(grouper.getAllModules(), module -> grouper.getModuleAsGroupPath(module));
68     for (final Module module : grouper.getAllModules()) {
69       List<String> group = grouper.getGroupPath(module);
70       if (myGroupPath.equals(group) || isChild(myGroupPath, group) && (recursively || isUnderGroupWithSameNameAsSomeModule(myGroupPath, group, moduleAsGroupsPaths))) {
71         result.add(module);
72       }
73     }
74     return result;
75   }
76
77   private static boolean isUnderGroupWithSameNameAsSomeModule(@NotNull List<String> parent, @NotNull List<String> descendant, @NotNull Set<List<String>> moduleNamesAsGroups) {
78     return descendant.size() > parent.size() && moduleNamesAsGroups.contains(descendant.subList(0, parent.size() + 1));
79   }
80
81   /**
82    * Returns direct subgroups of this group using cache built for default project grouper.
83    */
84   @NotNull
85   public Collection<ModuleGroup> childGroups(@NotNull Project project) {
86     return ModuleGroupsTree.getModuleGroupTree(project).getChildGroups(this);
87   }
88
89   @NotNull
90   public Collection<ModuleGroup> childGroups(@NotNull ModuleGrouper grouper) {
91     Set<ModuleGroup> result = new THashSet<>();
92     Set<List<String>> moduleAsGroupsPaths = ContainerUtil.map2Set(grouper.getAllModules(), module -> grouper.getModuleAsGroupPath(module));
93     for (Module module : grouper.getAllModules()) {
94       List<String> group = grouper.getGroupPath(module);
95       if (isChild(myGroupPath, group)) {
96         final List<String> directChild = ContainerUtil.append(myGroupPath, group.get(myGroupPath.size()));
97         if (!moduleAsGroupsPaths.contains(directChild)) {
98           result.add(new ModuleGroup(directChild));
99         }
100       }
101     }
102
103     return result;
104   }
105
106   private static boolean isChild(@NotNull List<String> parent, @NotNull List<String> descendant) {
107     return descendant.size() > parent.size() && descendant.subList(0, parent.size()).equals(parent);
108   }
109
110   @NotNull
111   public String presentableText() {
112     return "'" + myGroupPath.get(myGroupPath.size() - 1) + "'";
113   }
114
115   @NotNull
116   public String getQualifiedName() {
117     return StringUtil.join(myGroupPath, ".");
118   }
119
120   @Override
121   public @NlsSafe String toString() {
122     return myGroupPath.get(myGroupPath.size() - 1);
123   }
124 }