migrated to artifacts
[fedora-idea.git] / java / idea-ui / src / com / intellij / facet / impl / ProjectFacetsConfigurator.java
blob61ef8662c6b7b93d1a026842f2a769917b0465d8
1 /*
2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
3 */
5 package com.intellij.facet.impl;
7 import com.intellij.facet.*;
8 import com.intellij.facet.impl.ui.FacetEditorContextBase;
9 import com.intellij.facet.impl.ui.FacetEditorImpl;
10 import com.intellij.facet.impl.ui.FacetTreeModel;
11 import com.intellij.facet.impl.ui.ProjectConfigurableContext;
12 import com.intellij.facet.ui.FacetEditorContext;
13 import com.intellij.openapi.diagnostic.Logger;
14 import com.intellij.openapi.module.Module;
15 import com.intellij.openapi.options.ConfigurationException;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.roots.ModifiableRootModel;
18 import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
19 import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState;
20 import com.intellij.openapi.roots.ui.configuration.ModuleEditor;
21 import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator;
22 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
23 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory;
24 import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
25 import com.intellij.openapi.util.Disposer;
26 import com.intellij.openapi.util.UserDataHolder;
27 import com.intellij.openapi.util.UserDataHolderBase;
28 import org.jetbrains.annotations.NotNull;
29 import org.jetbrains.annotations.Nullable;
31 import java.util.*;
33 /**
34 * @author nik
36 public class ProjectFacetsConfigurator implements FacetsProvider, ModuleEditor.ChangeListener {
37 private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.ProjectFacetsConfigurator");
38 private final Map<Module, ModifiableFacetModel> myModels = new HashMap<Module, ModifiableFacetModel>();
39 private final Map<Facet, FacetEditorImpl> myEditors = new HashMap<Facet, FacetEditorImpl>();
40 private final Map<Module, FacetTreeModel> myTreeModels = new HashMap<Module, FacetTreeModel>();
41 private final Map<FacetInfo, Facet> myInfo2Facet = new HashMap<FacetInfo, Facet>();
42 private final Map<Facet, FacetInfo> myFacet2Info = new HashMap<Facet, FacetInfo>();
43 private final Map<Module, UserDataHolder> mySharedModuleData = new HashMap<Module, UserDataHolder>();
44 private final Set<Facet> myFacetsToDispose = new HashSet<Facet>();
45 private final Set<Facet> myChangedFacets = new HashSet<Facet>();
46 private final Set<Facet> myCreatedFacets = new HashSet<Facet>();
47 private final StructureConfigurableContext myContext;
48 private final Project myProject;
49 private UserDataHolderBase myProjectData = new UserDataHolderBase();
51 public ProjectFacetsConfigurator(final StructureConfigurableContext context, Project project) {
52 myContext = context;
53 myProject = project;
56 public List<Facet> removeFacet(Facet facet) {
57 FacetTreeModel treeModel = getTreeModel(facet.getModule());
58 FacetInfo facetInfo = myFacet2Info.get(facet);
59 if (facetInfo == null) return Collections.emptyList();
61 final List<Facet> removed = new ArrayList<Facet>();
62 List<FacetInfo> children = treeModel.getChildren(facetInfo);
63 for (FacetInfo child : children) {
64 Facet childInfo = myInfo2Facet.get(child);
65 if (childInfo != null) {
66 removed.addAll(removeFacet(childInfo));
70 treeModel.removeFacetInfo(facetInfo);
71 getOrCreateModifiableModel(facet.getModule()).removeFacet(facet);
72 myChangedFacets.remove(facet);
73 if (myCreatedFacets.contains(facet)) {
74 Disposer.dispose(facet);
76 final FacetEditorImpl facetEditor = myEditors.remove(facet);
77 if (facetEditor != null) {
78 facetEditor.disposeUIResources();
80 myFacet2Info.remove(facet);
81 myInfo2Facet.remove(facetInfo);
82 removed.add(facet);
83 return removed;
86 public Facet createAndAddFacet(Module module, FacetType<?, ?> type, String name, final @Nullable FacetInfo underlyingFacet) {
87 final Facet facet = FacetManager.getInstance(module).createFacet(type, name, myInfo2Facet.get(underlyingFacet));
88 myCreatedFacets.add(facet);
89 addFacetInfo(facet);
90 getOrCreateModifiableModel(module).addFacet(facet);
91 return facet;
94 public void addFacetInfo(final Facet facet) {
95 final FacetInfo exiting = myFacet2Info.get(facet);
96 if (exiting != null) {
97 LOG.assertTrue(exiting.getName().equals(facet.getName()));
98 LOG.assertTrue(exiting.getFacetType().equals(facet.getType()));
99 LOG.assertTrue(exiting.getConfiguration().equals(facet.getConfiguration()));
100 return;
103 FacetInfo info = new FacetInfo(facet.getType(), facet.getName(), facet.getConfiguration(), myFacet2Info.get(facet.getUnderlyingFacet()));
104 myFacet2Info.put(facet, info);
105 myInfo2Facet.put(info, facet);
106 getTreeModel(facet.getModule()).addFacetInfo(info);
109 public void addFacetInfos(final Module module) {
110 final Facet[] facets = getFacetModel(module).getSortedFacets();
111 for (Facet facet : facets) {
112 addFacetInfo(facet);
116 public void clearMaps() {
117 myModels.clear();
118 myEditors.clear();
119 myTreeModels.clear();
120 myInfo2Facet.clear();
121 myFacet2Info.clear();
122 myChangedFacets.clear();
123 mySharedModuleData.clear();
126 private boolean isNewFacet(Facet facet) {
127 final ModifiableFacetModel model = myModels.get(facet.getModule());
128 return model != null && model.isNewFacet(facet);
131 @NotNull
132 public ModifiableFacetModel getOrCreateModifiableModel(final Module module) {
133 ModifiableFacetModel model = myModels.get(module);
134 if (model == null) {
135 model = FacetManager.getInstance(module).createModifiableModel();
136 model.addListener(new ModifiableFacetModel.Listener() {
137 public void onChanged() {
138 fireFacetModelChanged(module);
140 }, null);
141 myModels.put(module, model);
143 return model;
146 @Nullable
147 public FacetEditorImpl getEditor(Facet facet) {
148 return myEditors.get(facet);
151 @NotNull
152 public FacetEditorImpl getOrCreateEditor(Facet facet) {
153 FacetEditorImpl editor = myEditors.get(facet);
154 if (editor == null) {
155 final Facet underlyingFacet = facet.getUnderlyingFacet();
156 final FacetEditorContext parentContext = underlyingFacet != null ? getOrCreateEditor(underlyingFacet).getContext() : null;
158 final FacetEditorContext context = createContext(facet, parentContext);
159 editor = new FacetEditorImpl(context, facet.getConfiguration());
160 editor.getComponent();
161 editor.reset();
162 myEditors.put(facet, editor);
164 return editor;
167 protected FacetEditorContext createContext(final @NotNull Facet facet, final @Nullable FacetEditorContext parentContext) {
168 Module module = facet.getModule();
169 ModulesConfigurator modulesConfigurator = myContext.getModulesConfigurator();
170 ModuleEditor moduleEditor = modulesConfigurator.getModuleEditor(module);
171 if (moduleEditor == null) {
172 LOG.error("ModuleEditor[" + module.getName() + "]==null: disposed = " + module.isDisposed() + ", is in model = "
173 + Arrays.asList(modulesConfigurator.getModules()).contains(module));
176 final ModuleConfigurationState state = moduleEditor.createModuleConfigurationState();
177 return new MyProjectConfigurableContext(facet, parentContext, state);
180 private UserDataHolder getSharedModuleData(final Module module) {
181 UserDataHolder dataHolder = mySharedModuleData.get(module);
182 if (dataHolder == null) {
183 dataHolder = new UserDataHolderBase();
184 mySharedModuleData.put(module, dataHolder);
186 return dataHolder;
189 @NotNull
190 public FacetModel getFacetModel(Module module) {
191 final ModifiableFacetModel model = myModels.get(module);
192 if (model != null) {
193 return model;
195 return FacetManager.getInstance(module);
198 public void commitFacets() {
199 for (ModifiableFacetModel model : myModels.values()) {
200 model.commit();
203 for (Map.Entry<Facet, FacetEditorImpl> entry : myEditors.entrySet()) {
204 entry.getValue().onFacetAdded(entry.getKey());
207 myModels.clear();
208 for (Facet facet : myChangedFacets) {
209 Module module = facet.getModule();
210 if (!module.isDisposed()) {
211 module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
214 myChangedFacets.clear();
217 public void resetEditors() {
218 for (FacetEditorImpl editor : myEditors.values()) {
219 editor.reset();
223 public void applyEditors() throws ConfigurationException {
224 for (Map.Entry<Facet, FacetEditorImpl> entry : myEditors.entrySet()) {
225 final FacetEditorImpl editor = entry.getValue();
226 if (editor.isModified()) {
227 myChangedFacets.add(entry.getKey());
229 editor.apply();
233 public boolean isModified() {
234 for (ModifiableFacetModel model : myModels.values()) {
235 if (model.isModified()) {
236 return true;
239 for (FacetEditorImpl editor : myEditors.values()) {
240 if (editor.isModified()) {
241 return true;
244 return false;
247 public FacetTreeModel getTreeModel(Module module) {
248 FacetTreeModel treeModel = myTreeModels.get(module);
249 if (treeModel == null) {
250 treeModel = new FacetTreeModel();
251 myTreeModels.put(module, treeModel);
253 return treeModel;
256 public FacetInfo getFacetInfo(final Facet facet) {
257 return myFacet2Info.get(facet);
260 public Facet getFacet(final FacetInfo facetInfo) {
261 return myInfo2Facet.get(facetInfo);
264 public void disposeEditors() {
265 for (Facet facet : myFacetsToDispose) {
266 Disposer.dispose(facet);
268 myFacetsToDispose.clear();
269 myCreatedFacets.clear();
271 for (FacetEditorImpl editor : myEditors.values()) {
272 editor.disposeUIResources();
274 myProjectData = null;
277 @NotNull
278 public Facet[] getAllFacets(final Module module) {
279 return getFacetModel(module).getAllFacets();
282 @NotNull
283 public <F extends Facet> Collection<F> getFacetsByType(final Module module, final FacetTypeId<F> type) {
284 return getFacetModel(module).getFacetsByType(type);
287 @Nullable
288 public <F extends Facet> F findFacet(final Module module, final FacetTypeId<F> type, final String name) {
289 return getFacetModel(module).findFacet(type, name);
292 public void moduleStateChanged(final ModifiableRootModel moduleRootModel) {
293 Module module = moduleRootModel.getModule();
294 Facet[] allFacets = getAllFacets(module);
295 for (Facet facet : allFacets) {
296 FacetEditorImpl facetEditor = myEditors.get(facet);
297 if (facetEditor != null) {
298 ((FacetEditorContextBase)facetEditor.getContext()).fireModuleRootsChanged(moduleRootModel);
303 private void fireFacetModelChanged(Module module) {
304 for (Facet facet : getAllFacets(module)) {
305 FacetEditorImpl facetEditor = myEditors.get(facet);
306 if (facetEditor != null) {
307 ((FacetEditorContextBase)facetEditor.getContext()).fireFacetModelChanged(module);
312 private UserDataHolder getProjectData() {
313 if (myProjectData == null) {
314 myProjectData = new UserDataHolderBase();
316 return myProjectData;
319 public List<Facet> removeAllFacets(final Module module) {
320 List<Facet> facets = new ArrayList<Facet>();
321 FacetModel facetModel = getOrCreateModifiableModel(module);
322 for (Facet facet : facetModel.getAllFacets()) {
323 if (!myCreatedFacets.contains(facet)) {
324 myFacetsToDispose.add(facet);
326 LOG.assertTrue(facet.getModule().equals(module), module + " expected but " + facet.getModule() + " found");
327 facets.addAll(removeFacet(facet));
329 mySharedModuleData.remove(module);
330 myModels.remove(module);
331 return facets;
334 private class MyProjectConfigurableContext extends ProjectConfigurableContext {
335 private final LibrariesContainer myContainer;
337 public MyProjectConfigurableContext(final Facet facet, final FacetEditorContext parentContext, final ModuleConfigurationState state) {
338 super(facet, ProjectFacetsConfigurator.this.isNewFacet(facet), parentContext, state,
339 ProjectFacetsConfigurator.this.getSharedModuleData(facet.getModule()), getProjectData());
340 myContainer = LibrariesContainerFactory.createContainer(facet.getModule().getProject(), myContext);
343 public LibrariesContainer getContainer() {
344 return myContainer;