[platform] get rid of some raw types in facets API and impl
[idea/community.git] / platform / lang-impl / src / com / intellij / facet / impl / ProjectFacetManagerImpl.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.components.PersistentStateComponent;
8 import com.intellij.openapi.components.State;
9 import com.intellij.openapi.diagnostic.Logger;
10 import com.intellij.openapi.module.Module;
11 import com.intellij.openapi.module.ModuleManager;
12 import com.intellij.openapi.project.ModuleListener;
13 import com.intellij.openapi.project.Project;
14 import com.intellij.openapi.util.InvalidDataException;
15 import com.intellij.openapi.util.WriteExternalException;
16 import com.intellij.util.containers.ContainerUtil;
17 import com.intellij.util.containers.MultiMap;
18 import com.intellij.util.xmlb.annotations.MapAnnotation;
19 import com.intellij.util.xmlb.annotations.Tag;
20 import org.jdom.Element;
21 import org.jetbrains.annotations.NonNls;
22 import org.jetbrains.annotations.NotNull;
23
24 import java.util.*;
25
26 @State(name = ProjectFacetManagerImpl.COMPONENT_NAME)
27 public class ProjectFacetManagerImpl extends ProjectFacetManagerEx implements PersistentStateComponent<ProjectFacetManagerImpl.ProjectFacetManagerState> {
28   @NonNls public static final String COMPONENT_NAME = "ProjectFacetManager";
29   private static final Logger LOG = Logger.getInstance(ProjectFacetManagerImpl.class);
30   private ProjectFacetManagerState myState = new ProjectFacetManagerState();
31   private final Project myProject;
32   private volatile MultiMap<FacetTypeId<?>, Module> myIndex;
33
34   public ProjectFacetManagerImpl(Project project) {
35     myProject = project;
36
37     ProjectWideFacetListenersRegistry.getInstance(project).registerListener(new ProjectWideFacetAdapter<Facet>() {
38       @Override
39       public void facetAdded(@NotNull Facet facet) {
40         myIndex = null;
41       }
42
43       @Override
44       public void facetRemoved(@NotNull Facet facet) {
45         myIndex = null;
46       }
47     }, project);
48     project.getMessageBus().connect().subscribe(ProjectTopics.MODULES, new ModuleListener() {
49       @Override
50       public void moduleAdded(@NotNull Project project, @NotNull Module module) {
51         myIndex = null;
52       }
53
54       @Override
55       public void moduleRemoved(@NotNull Project project, @NotNull Module module) {
56         myIndex = null;
57       }
58     });
59   }
60
61   @Override
62   public ProjectFacetManagerState getState() {
63     return myState;
64   }
65
66   @Override
67   public void loadState(@NotNull final ProjectFacetManagerState state) {
68     myState = state;
69   }
70
71   @NotNull
72   private MultiMap<FacetTypeId<?>, Module> getIndex() {
73     MultiMap<FacetTypeId<?>, Module> index = myIndex;
74     if (index == null) {
75       index = MultiMap.createLinked();
76       for (Module module : ModuleManager.getInstance(myProject).getModules()) {
77         for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
78           index.putValue(facet.getTypeId(), module);
79         }
80       }
81       myIndex = index;
82     }
83     return index;
84   }
85
86   @NotNull
87   @Override
88   public <F extends Facet<?>> List<F> getFacets(@NotNull FacetTypeId<F> typeId) {
89     return ContainerUtil.concat(getIndex().get(typeId), module -> FacetManager.getInstance(module).getFacetsByType(typeId));
90   }
91
92   @NotNull
93   @Override
94   public List<Module> getModulesWithFacet(@NotNull FacetTypeId<?> typeId) {
95     //noinspection unchecked
96     return Collections.unmodifiableList((List)getIndex().get(typeId));
97   }
98
99   @Override
100   public boolean hasFacets(@NotNull FacetTypeId<?> typeId) {
101     return getIndex().containsKey(typeId);
102   }
103
104   @Override
105   public <F extends Facet<?>> List<F> getFacets(@NotNull FacetTypeId<F> typeId, final Module[] modules) {
106     final List<F> result = new ArrayList<>();
107     for (Module module : modules) {
108       result.addAll(FacetManager.getInstance(module).getFacetsByType(typeId));
109     }
110     return result;
111   }
112
113   @Override
114   public <C extends FacetConfiguration> C createDefaultConfiguration(@NotNull final FacetType<?, C> facetType) {
115     C configuration = facetType.createDefaultConfiguration();
116     DefaultFacetConfigurationState state = myState.getDefaultConfigurations().get(facetType.getStringId());
117     if (state != null) {
118       Element defaultConfiguration = state.getDefaultConfiguration();
119       try {
120         FacetUtil.loadFacetConfiguration(configuration, defaultConfiguration);
121       }
122       catch (InvalidDataException e) {
123         LOG.info(e);
124       }
125     }
126     return configuration;
127   }
128
129   @Override
130   public <C extends FacetConfiguration> void setDefaultConfiguration(@NotNull final FacetType<?, C> facetType, @NotNull final C configuration) {
131     Map<String, DefaultFacetConfigurationState> defaultConfigurations = myState.getDefaultConfigurations();
132     DefaultFacetConfigurationState state = defaultConfigurations.get(facetType.getStringId());
133     if (state == null) {
134       state = new DefaultFacetConfigurationState();
135       defaultConfigurations.put(facetType.getStringId(), state);
136     }
137     try {
138       Element element = FacetUtil.saveFacetConfiguration(configuration);
139       state.setDefaultConfiguration(element);
140     }
141     catch (WriteExternalException e) {
142       LOG.info(e);
143     }
144   }
145
146   @Tag("default-facet-configuration")
147   public static class DefaultFacetConfigurationState {
148     private Element myDefaultConfiguration;
149
150     @Tag("configuration")
151     public Element getDefaultConfiguration() {
152       return myDefaultConfiguration;
153     }
154
155     public void setDefaultConfiguration(final Element defaultConfiguration) {
156       myDefaultConfiguration = defaultConfiguration;
157     }
158   }
159
160   public static class ProjectFacetManagerState {
161     private Map<String, DefaultFacetConfigurationState> myDefaultConfigurations = new HashMap<>();
162
163     @Tag("default-configurations")
164     @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false, //entryTagName = "default-configuration",
165                    keyAttributeName = "facet-type")
166     public Map<String, DefaultFacetConfigurationState> getDefaultConfigurations() {
167       return myDefaultConfigurations;
168     }
169
170     public void setDefaultConfigurations(final Map<String, DefaultFacetConfigurationState> defaultConfigurations) {
171       myDefaultConfigurations = defaultConfigurations;
172     }
173   }
174 }