ce3253ea9e0652daf98625404c070add8062604f
[idea/community.git] / platform / lang-impl / src / com / intellij / openapi / roots / impl / libraries / LibraryKindLoader.java
1 // Copyright 2000-2018 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.impl.libraries;
3
4 import com.intellij.ide.ApplicationInitializedListener;
5 import com.intellij.openapi.application.WriteAction;
6 import com.intellij.openapi.extensions.ExtensionPointListener;
7 import com.intellij.openapi.extensions.PluginDescriptor;
8 import com.intellij.openapi.module.Module;
9 import com.intellij.openapi.module.ModuleManager;
10 import com.intellij.openapi.project.Project;
11 import com.intellij.openapi.project.ProjectManager;
12 import com.intellij.openapi.roots.ModuleRootManager;
13 import com.intellij.openapi.roots.impl.OrderEntryUtil;
14 import com.intellij.openapi.roots.libraries.*;
15 import org.jetbrains.annotations.NotNull;
16
17 import java.util.function.Consumer;
18
19 public class LibraryKindLoader implements ApplicationInitializedListener {
20   @Override
21   public void componentsInitialized() {
22     //todo[nik] this is temporary workaround for IDEA-98118: we need to initialize all library types to ensure that their kinds are created and registered in LibraryKind.ourAllKinds
23     //In order to properly fix the problem we should extract all UI-related methods from LibraryType to a separate class and move LibraryType to intellij.platform.projectModel.impl module
24     LibraryType.EP_NAME.getExtensionList();
25
26     LibraryType.EP_NAME.addExtensionPointListener(new ExtensionPointListener<LibraryType<?>>() {
27       @Override
28       public void extensionAdded(@NotNull LibraryType<?> extension, @NotNull PluginDescriptor pluginDescriptor) {
29         WriteAction.run(() -> {
30           LibraryKind.registerKind(extension.getKind());
31           processAllLibraries(library -> rememberKind(extension.getKind(), library));
32         });
33       }
34
35       @Override
36       public void extensionRemoved(@NotNull LibraryType<?> extension, @NotNull PluginDescriptor pluginDescriptor) {
37         LibraryKind.unregisterKind(extension.getKind());
38         processAllLibraries(library -> forgetKind(extension.getKind(), library));
39       }
40     }, null);
41   }
42
43   private static void processAllLibraries(@NotNull Consumer<Library> processor) {
44     processLibraries(LibraryTablesRegistrar.getInstance().getLibraryTable(), processor);
45     for (LibraryTable table : LibraryTablesRegistrar.getInstance().getCustomLibraryTables()) {
46       processLibraries(table, processor);
47     }
48     for (Project project : ProjectManager.getInstance().getOpenProjects()) {
49       processLibraries(LibraryTablesRegistrar.getInstance().getLibraryTable(project), processor);
50       for (Module module : ModuleManager.getInstance(project).getModules()) {
51         for (Library library : OrderEntryUtil.getModuleLibraries(ModuleRootManager.getInstance(module))) {
52           processor.accept(library);
53         }
54       }
55     }
56   }
57
58   private static void processLibraries(@NotNull LibraryTable table, Consumer<Library> processor) {
59     for (Library library : table.getLibraries()) {
60       processor.accept(library);
61     }
62   }
63
64   private static void forgetKind(@NotNull PersistentLibraryKind<?> kind, @NotNull Library library) {
65     if (kind.equals(((LibraryEx)library).getKind())) {
66       LibraryEx.ModifiableModelEx model = (LibraryEx.ModifiableModelEx)library.getModifiableModel();
67       model.forgetKind();
68       model.commit();
69     }
70   }
71
72   private static void rememberKind(@NotNull PersistentLibraryKind<?> kind, @NotNull Library library) {
73     PersistentLibraryKind<?> libraryKind = ((LibraryEx)library).getKind();
74     if (libraryKind instanceof UnknownLibraryKind && libraryKind.getKindId().equals(kind.getKindId())) {
75       LibraryEx.ModifiableModelEx model = (LibraryEx.ModifiableModelEx)library.getModifiableModel();
76       model.restoreKind();
77       model.commit();
78     }
79   }
80 }