IDEA-246442 Incorrect symbol for drop down list
[idea/community.git] / platform / projectModel-api / src / com / intellij / openapi / roots / ModuleRootModificationUtil.java
1 // Copyright 2000-2020 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 package com.intellij.openapi.roots;
3
4 import com.intellij.openapi.application.ApplicationManager;
5 import com.intellij.openapi.application.ReadAction;
6 import com.intellij.openapi.application.WriteAction;
7 import com.intellij.openapi.module.Module;
8 import com.intellij.openapi.projectRoots.Sdk;
9 import com.intellij.openapi.roots.impl.libraries.LibraryEx;
10 import com.intellij.openapi.roots.libraries.Library;
11 import com.intellij.openapi.vfs.VfsUtilCore;
12 import com.intellij.openapi.vfs.VirtualFile;
13 import com.intellij.util.Consumer;
14 import org.jetbrains.annotations.NotNull;
15 import org.jetbrains.annotations.Nullable;
16
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.List;
20 import java.util.function.Function;
21
22 public final class ModuleRootModificationUtil {
23   public static void addContentRoot(@NotNull Module module, @NotNull String path) {
24     updateModel(module, model -> model.addContentEntry(VfsUtilCore.pathToUrl(path)));
25   }
26
27   public static void addContentRoot(@NotNull Module module, @NotNull VirtualFile path) {
28     updateModel(module, model -> model.addContentEntry(path));
29   }
30
31   public static void addModuleLibrary(@NotNull Module module,
32                                       @Nullable String libName,
33                                       @NotNull List<String> classesRootUrls,
34                                       @NotNull List<String> sourceRootUrls) {
35     addModuleLibrary(module, libName, classesRootUrls, sourceRootUrls, DependencyScope.COMPILE);
36   }
37
38   public static void addModuleLibrary(@NotNull Module module,
39                                       @Nullable String libName,
40                                       @NotNull List<String> classesRootUrls,
41                                       @NotNull List<String> sourceRootUrls,
42                                       @NotNull DependencyScope scope) {
43     addModuleLibrary(module, libName, classesRootUrls, sourceRootUrls, Collections.emptyList(), scope);
44   }
45
46   public static void addModuleLibrary(@NotNull Module module,
47                                       @Nullable String libName,
48                                       @NotNull List<String> classesRootUrls,
49                                       @NotNull List<String> sourceRootUrls,
50                                       @NotNull List<String> excludedRootUrls,
51                                       @NotNull DependencyScope scope) {
52     addModuleLibrary(module, libName, classesRootUrls, sourceRootUrls, excludedRootUrls, scope, false);
53   }
54
55   public static void addModuleLibrary(@NotNull Module module,
56                                       @Nullable String libName,
57                                       @NotNull List<String> classesRootUrls,
58                                       @NotNull List<String> sourceRootUrls,
59                                       @NotNull List<String> excludedRootUrls,
60                                       @NotNull DependencyScope scope,
61                                       boolean exported) {
62     updateModel(module, model -> {
63       LibraryEx library = (LibraryEx)model.getModuleLibraryTable().createLibrary(libName);
64       LibraryEx.ModifiableModelEx libraryModel = library.getModifiableModel();
65
66       for (String rootUrl : classesRootUrls) {
67         libraryModel.addRoot(rootUrl, OrderRootType.CLASSES);
68       }
69       for (String rootUrl : sourceRootUrls) {
70         libraryModel.addRoot(rootUrl, OrderRootType.SOURCES);
71       }
72       for (String excludedUrl : excludedRootUrls) {
73         libraryModel.addExcludedRoot(excludedUrl);
74       }
75
76       LibraryOrderEntry entry = model.findLibraryOrderEntry(library);
77       assert entry != null : library;
78       entry.setScope(scope);
79       entry.setExported(exported);
80
81       ApplicationManager.getApplication().invokeAndWait(() -> WriteAction.run(libraryModel::commit));
82     });
83   }
84
85   public static void addModuleLibrary(@NotNull Module module, @NotNull String classesRootUrl) {
86     if (ApplicationManager.getApplication().isUnitTestMode() && classesRootUrl.endsWith(".jar")) {
87       assert false : "jar file is expected, local file is used";
88     }
89     addModuleLibrary(module, null, Collections.singletonList(classesRootUrl), Collections.emptyList());
90   }
91
92   public static void addDependency(@NotNull Module module, @NotNull Library library) {
93     addDependency(module, library, DependencyScope.COMPILE, false);
94   }
95
96   public static void addDependency(@NotNull Module module, @NotNull Library library, @NotNull DependencyScope scope, boolean exported) {
97     updateModel(module, model -> {
98       LibraryOrderEntry entry = model.addLibraryEntry(library);
99       entry.setExported(exported);
100       entry.setScope(scope);
101     });
102   }
103
104   public static void setModuleSdk(@NotNull Module module, @Nullable Sdk sdk) {
105     updateModel(module, model -> model.setSdk(sdk));
106   }
107
108   public static void setSdkInherited(@NotNull Module module) {
109     updateModel(module, model -> model.inheritSdk());
110   }
111
112   public static void addDependency(@NotNull Module from, @NotNull Module to) {
113     addDependency(from, to, DependencyScope.COMPILE, false);
114   }
115
116   public static void addDependency(@NotNull Module from, @NotNull Module to, @NotNull DependencyScope scope, boolean exported) {
117     updateModel(from, model -> {
118       ModuleOrderEntry entry = model.addModuleOrderEntry(to);
119       entry.setScope(scope);
120       entry.setExported(exported);
121     });
122   }
123
124   public static void updateModel(@NotNull Module module, @NotNull Consumer<? super ModifiableRootModel> task) {
125     modifyModel(module, model -> {
126       task.consume(model);
127       return Boolean.TRUE;
128     });
129   }
130
131   public static void modifyModel(@NotNull Module module, @NotNull Function<? super ModifiableRootModel, Boolean> modifier) {
132     ModifiableRootModel model = ReadAction.compute(() -> ModuleRootManager.getInstance(module).getModifiableModel());
133     try {
134       if (modifier.apply(model)) {
135         ApplicationManager.getApplication().invokeAndWait(() -> {
136           if (!module.isDisposed()) {
137             WriteAction.run(model::commit);
138           }
139         });
140       }
141     }
142     finally {
143       if (!model.isDisposed()) {
144         model.dispose();
145       }
146     }
147   }
148
149   public static void updateExcludedFolders(@NotNull Module module,
150                                            @NotNull VirtualFile contentRoot,
151                                            @NotNull Collection<String> urlsToUnExclude,
152                                            @NotNull Collection<String> urlsToExclude) {
153     updateModel(module, modifiableModel -> {
154       for (ContentEntry contentEntry : modifiableModel.getContentEntries()) {
155         if (contentRoot.equals(contentEntry.getFile())) {
156           for (String url : urlsToUnExclude) {
157             contentEntry.removeExcludeFolder(url);
158           }
159           for (String url : urlsToExclude) {
160             contentEntry.addExcludeFolder(url);
161           }
162           break;
163         }
164       }
165     });
166   }
167 }