[platform] get rid of some raw types in facets API and impl
[idea/community.git] / platform / lang-impl / src / com / intellij / facet / impl / ProjectWideFacetListenersRegistryImpl.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.facet.impl;
4
5 import com.intellij.ProjectTopics;
6 import com.intellij.facet.*;
7 import com.intellij.openapi.Disposable;
8 import com.intellij.openapi.module.Module;
9 import com.intellij.openapi.module.ModuleManager;
10 import com.intellij.openapi.project.ModuleListener;
11 import com.intellij.openapi.project.Project;
12 import com.intellij.openapi.util.Disposer;
13 import com.intellij.util.EventDispatcher;
14 import com.intellij.util.containers.ContainerUtil;
15 import com.intellij.util.messages.MessageBusConnection;
16 import org.jetbrains.annotations.NotNull;
17
18 import java.util.HashMap;
19 import java.util.Map;
20
21 public final class ProjectWideFacetListenersRegistryImpl extends ProjectWideFacetListenersRegistry {
22   private final Map<FacetTypeId<?>, EventDispatcher<ProjectWideFacetListener>> myDispatchers = new HashMap<>();
23   private final Map<FacetTypeId<?>, Map<Facet<?>, Boolean>> myFacetsByType = new HashMap<>();
24   private final Map<Module, MessageBusConnection> myModule2Connection = new HashMap<>();
25   private final FacetManagerAdapter myFacetListener;
26   private final EventDispatcher<ProjectWideFacetListener> myAllFacetsListener = EventDispatcher.create(ProjectWideFacetListener.class);
27
28   public ProjectWideFacetListenersRegistryImpl(@NotNull Project project) {
29     myFacetListener = new MyFacetManagerAdapter();
30     project.getMessageBus().connect().subscribe(ProjectTopics.MODULES, new ModuleListener() {
31       @Override
32       public void moduleAdded(@NotNull Project project, @NotNull Module module) {
33         onModuleAdded(module);
34       }
35
36       @Override
37       public void beforeModuleRemoved(@NotNull final Project project, @NotNull final Module module) {
38         Facet<?>[] allFacets = FacetManager.getInstance(module).getAllFacets();
39         for (Facet<?> facet : allFacets) {
40           onFacetRemoved(facet, true);
41         }
42       }
43
44       @Override
45       public void moduleRemoved(@NotNull Project project, @NotNull Module module) {
46         onModuleRemoved(module);
47       }
48     });
49
50     for (Module module : ModuleManager.getInstance(project).getModules()) {
51       onModuleAdded(module);
52     }
53   }
54
55   private void onModuleRemoved(final Module module) {
56     final MessageBusConnection connection = myModule2Connection.remove(module);
57     if (connection != null) {
58       connection.disconnect();
59     }
60
61     final FacetManager facetManager = FacetManager.getInstance(module);
62     final Facet<?>[] facets = facetManager.getAllFacets();
63     for (Facet<?> facet : facets) {
64       onFacetRemoved(facet, false);
65     }
66   }
67
68   private void onModuleAdded(final Module module) {
69     final FacetManager facetManager = FacetManager.getInstance(module);
70     final Facet<?>[] facets = facetManager.getAllFacets();
71     for (Facet<?> facet : facets) {
72       onFacetAdded(facet);
73     }
74     final MessageBusConnection connection = module.getMessageBus().connect();
75     myModule2Connection.put(module, connection);
76     connection.subscribe(FacetManager.FACETS_TOPIC, myFacetListener);
77   }
78
79   private void onFacetRemoved(@NotNull Facet<?> facet, final boolean before) {
80     final FacetTypeId<?> typeId = facet.getTypeId();
81     Map<Facet<?>, Boolean> facets = myFacetsByType.get(typeId);
82     boolean lastFacet;
83     if (facets != null) {
84       facets.remove(facet);
85       lastFacet = facets.isEmpty();
86       if (lastFacet) {
87         myFacetsByType.remove(typeId);
88       }
89     }
90     else {
91       lastFacet = true;
92     }
93     final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
94     if (dispatcher != null) {
95       if (before) {
96         //noinspection unchecked
97         dispatcher.getMulticaster().beforeFacetRemoved(facet);
98       }
99       else {
100         //noinspection unchecked
101         dispatcher.getMulticaster().facetRemoved(facet);
102         if (lastFacet) {
103           dispatcher.getMulticaster().allFacetsRemoved();
104         }
105       }
106     }
107
108     if (before) {
109       getAllFacetsMulticaster().beforeFacetRemoved(facet);
110     }
111     else {
112       getAllFacetsMulticaster().facetRemoved(facet);
113       if (myFacetsByType.isEmpty()) {
114         getAllFacetsMulticaster().allFacetsRemoved();
115       }
116     }
117   }
118
119   private ProjectWideFacetListener<Facet<?>> getAllFacetsMulticaster() {
120     //noinspection unchecked
121     return myAllFacetsListener.getMulticaster();
122   }
123
124   private void onFacetAdded(@NotNull Facet<?> facet) {
125     boolean firstFacet = myFacetsByType.isEmpty();
126     final FacetTypeId<?> typeId = facet.getTypeId();
127     Map<Facet<?>, Boolean> facets = myFacetsByType.get(typeId);
128     if (facets == null) {
129       facets = ContainerUtil.createWeakMap();
130       myFacetsByType.put(typeId, facets);
131     }
132     boolean firstFacetOfType = facets.isEmpty();
133     facets.put(facet, true);
134
135     if (firstFacet) {
136       getAllFacetsMulticaster().firstFacetAdded();
137     }
138     getAllFacetsMulticaster().facetAdded(facet);
139
140     final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
141     if (dispatcher != null) {
142       if (firstFacetOfType) {
143         dispatcher.getMulticaster().firstFacetAdded();
144       }
145       //noinspection unchecked
146       dispatcher.getMulticaster().facetAdded(facet);
147     }
148   }
149
150   private void onFacetChanged(@NotNull Facet<?> facet) {
151     final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(facet.getTypeId());
152     if (dispatcher != null) {
153       //noinspection unchecked
154       dispatcher.getMulticaster().facetConfigurationChanged(facet);
155     }
156     getAllFacetsMulticaster().facetConfigurationChanged(facet);
157   }
158
159   @Override
160   public <F extends Facet<?>> void registerListener(@NotNull FacetTypeId<F> typeId, @NotNull ProjectWideFacetListener<? extends F> listener) {
161     EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
162     if (dispatcher == null) {
163       dispatcher = EventDispatcher.create(ProjectWideFacetListener.class);
164       myDispatchers.put(typeId, dispatcher);
165     }
166     dispatcher.addListener(listener);
167   }
168
169   @Override
170   public <F extends Facet<?>> void unregisterListener(@NotNull FacetTypeId<F> typeId, @NotNull ProjectWideFacetListener<? extends F> listener) {
171     final EventDispatcher<ProjectWideFacetListener> dispatcher = myDispatchers.get(typeId);
172     if (dispatcher != null) {
173       dispatcher.removeListener(listener);
174     }
175   }
176
177   @Override
178   public <F extends Facet<?>> void registerListener(@NotNull final FacetTypeId<F> typeId, @NotNull final ProjectWideFacetListener<? extends F> listener,
179                                                  @NotNull final Disposable parentDisposable) {
180     registerListener(typeId, listener);
181     Disposer.register(parentDisposable, new Disposable() {
182       @Override
183       public void dispose() {
184         unregisterListener(typeId, listener);
185       }
186     });
187   }
188
189   @Override
190   public void registerListener(@NotNull final ProjectWideFacetListener<Facet> listener) {
191     myAllFacetsListener.addListener(listener);
192   }
193
194   @Override
195   public void unregisterListener(@NotNull final ProjectWideFacetListener<Facet> listener) {
196     myAllFacetsListener.removeListener(listener);
197   }
198
199   @Override
200   public void registerListener(@NotNull final ProjectWideFacetListener<Facet> listener, @NotNull final Disposable parentDisposable) {
201     myAllFacetsListener.addListener(listener, parentDisposable);
202   }
203
204   private class MyFacetManagerAdapter extends FacetManagerAdapter {
205
206     @Override
207     public void facetAdded(@NotNull Facet facet) {
208       onFacetAdded(facet);
209     }
210
211     @Override
212     public void beforeFacetRemoved(@NotNull final Facet facet) {
213       onFacetRemoved(facet, true);
214     }
215
216     @Override
217     public void facetRemoved(@NotNull Facet facet) {
218       onFacetRemoved(facet, false);
219     }
220
221     @Override
222     public void facetConfigurationChanged(@NotNull final Facet facet) {
223       onFacetChanged(facet);
224     }
225
226   }
227 }