update copyright
[fedora-idea.git] / java / idea-ui / src / com / intellij / facet / impl / ProjectFacetsConfigurator.java
blob5443a36cad965c5776c726388c43896a8974ccbd
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.facet.impl;
19 import com.intellij.facet.*;
20 import com.intellij.facet.impl.ui.FacetEditorContextBase;
21 import com.intellij.facet.impl.ui.FacetEditorImpl;
22 import com.intellij.facet.impl.ui.FacetTreeModel;
23 import com.intellij.facet.impl.ui.ProjectConfigurableContext;
24 import com.intellij.facet.ui.FacetEditorContext;
25 import com.intellij.openapi.diagnostic.Logger;
26 import com.intellij.openapi.module.Module;
27 import com.intellij.openapi.options.ConfigurationException;
28 import com.intellij.openapi.project.Project;
29 import com.intellij.openapi.roots.ModifiableRootModel;
30 import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
31 import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState;
32 import com.intellij.openapi.roots.ui.configuration.ModuleEditor;
33 import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator;
34 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
35 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory;
36 import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
37 import com.intellij.openapi.util.Disposer;
38 import com.intellij.openapi.util.UserDataHolder;
39 import com.intellij.openapi.util.UserDataHolderBase;
40 import org.jetbrains.annotations.NotNull;
41 import org.jetbrains.annotations.Nullable;
43 import java.util.*;
45 /**
46 * @author nik
48 public class ProjectFacetsConfigurator implements FacetsProvider, ModuleEditor.ChangeListener {
49 private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.ProjectFacetsConfigurator");
50 private final Map<Module, ModifiableFacetModel> myModels = new HashMap<Module, ModifiableFacetModel>();
51 private final Map<Facet, FacetEditorImpl> myEditors = new HashMap<Facet, FacetEditorImpl>();
52 private final Map<Module, FacetTreeModel> myTreeModels = new HashMap<Module, FacetTreeModel>();
53 private final Map<FacetInfo, Facet> myInfo2Facet = new HashMap<FacetInfo, Facet>();
54 private final Map<Facet, FacetInfo> myFacet2Info = new HashMap<Facet, FacetInfo>();
55 private final Map<Module, UserDataHolder> mySharedModuleData = new HashMap<Module, UserDataHolder>();
56 private final Set<Facet> myFacetsToDispose = new HashSet<Facet>();
57 private final Set<Facet> myChangedFacets = new HashSet<Facet>();
58 private final Set<Facet> myCreatedFacets = new HashSet<Facet>();
59 private final StructureConfigurableContext myContext;
60 private final Project myProject;
61 private UserDataHolderBase myProjectData = new UserDataHolderBase();
63 public ProjectFacetsConfigurator(final StructureConfigurableContext context, Project project) {
64 myContext = context;
65 myProject = project;
68 public List<Facet> removeFacet(Facet facet) {
69 FacetTreeModel treeModel = getTreeModel(facet.getModule());
70 FacetInfo facetInfo = myFacet2Info.get(facet);
71 if (facetInfo == null) return Collections.emptyList();
73 final List<Facet> removed = new ArrayList<Facet>();
74 List<FacetInfo> children = treeModel.getChildren(facetInfo);
75 for (FacetInfo child : children) {
76 Facet childInfo = myInfo2Facet.get(child);
77 if (childInfo != null) {
78 removed.addAll(removeFacet(childInfo));
82 treeModel.removeFacetInfo(facetInfo);
83 getOrCreateModifiableModel(facet.getModule()).removeFacet(facet);
84 myChangedFacets.remove(facet);
85 if (myCreatedFacets.contains(facet)) {
86 Disposer.dispose(facet);
88 final FacetEditorImpl facetEditor = myEditors.remove(facet);
89 if (facetEditor != null) {
90 facetEditor.disposeUIResources();
92 myFacet2Info.remove(facet);
93 myInfo2Facet.remove(facetInfo);
94 removed.add(facet);
95 return removed;
98 public Facet createAndAddFacet(Module module, FacetType<?, ?> type, String name, final @Nullable FacetInfo underlyingFacet) {
99 final Facet facet = FacetManager.getInstance(module).createFacet(type, name, myInfo2Facet.get(underlyingFacet));
100 myCreatedFacets.add(facet);
101 addFacetInfo(facet);
102 getOrCreateModifiableModel(module).addFacet(facet);
103 return facet;
106 public void addFacetInfo(final Facet facet) {
107 final FacetInfo exiting = myFacet2Info.get(facet);
108 if (exiting != null) {
109 LOG.assertTrue(exiting.getName().equals(facet.getName()));
110 LOG.assertTrue(exiting.getFacetType().equals(facet.getType()));
111 LOG.assertTrue(exiting.getConfiguration().equals(facet.getConfiguration()));
112 return;
115 FacetInfo info = new FacetInfo(facet.getType(), facet.getName(), facet.getConfiguration(), myFacet2Info.get(facet.getUnderlyingFacet()));
116 myFacet2Info.put(facet, info);
117 myInfo2Facet.put(info, facet);
118 getTreeModel(facet.getModule()).addFacetInfo(info);
121 public void addFacetInfos(final Module module) {
122 final Facet[] facets = getFacetModel(module).getSortedFacets();
123 for (Facet facet : facets) {
124 addFacetInfo(facet);
128 public void clearMaps() {
129 myModels.clear();
130 myEditors.clear();
131 myTreeModels.clear();
132 myInfo2Facet.clear();
133 myFacet2Info.clear();
134 myChangedFacets.clear();
135 mySharedModuleData.clear();
138 private boolean isNewFacet(Facet facet) {
139 final ModifiableFacetModel model = myModels.get(facet.getModule());
140 return model != null && model.isNewFacet(facet);
143 @NotNull
144 public ModifiableFacetModel getOrCreateModifiableModel(final Module module) {
145 ModifiableFacetModel model = myModels.get(module);
146 if (model == null) {
147 model = FacetManager.getInstance(module).createModifiableModel();
148 model.addListener(new ModifiableFacetModel.Listener() {
149 public void onChanged() {
150 fireFacetModelChanged(module);
152 }, null);
153 myModels.put(module, model);
155 return model;
158 @Nullable
159 public FacetEditorImpl getEditor(Facet facet) {
160 return myEditors.get(facet);
163 @NotNull
164 public FacetEditorImpl getOrCreateEditor(Facet facet) {
165 FacetEditorImpl editor = myEditors.get(facet);
166 if (editor == null) {
167 final Facet underlyingFacet = facet.getUnderlyingFacet();
168 final FacetEditorContext parentContext = underlyingFacet != null ? getOrCreateEditor(underlyingFacet).getContext() : null;
170 final FacetEditorContext context = createContext(facet, parentContext);
171 editor = new FacetEditorImpl(context, facet.getConfiguration());
172 editor.getComponent();
173 editor.reset();
174 myEditors.put(facet, editor);
176 return editor;
179 protected FacetEditorContext createContext(final @NotNull Facet facet, final @Nullable FacetEditorContext parentContext) {
180 Module module = facet.getModule();
181 ModulesConfigurator modulesConfigurator = myContext.getModulesConfigurator();
182 ModuleEditor moduleEditor = modulesConfigurator.getModuleEditor(module);
183 if (moduleEditor == null) {
184 LOG.error("ModuleEditor[" + module.getName() + "]==null: disposed = " + module.isDisposed() + ", is in model = "
185 + Arrays.asList(modulesConfigurator.getModules()).contains(module));
188 final ModuleConfigurationState state = moduleEditor.createModuleConfigurationState();
189 return new MyProjectConfigurableContext(facet, parentContext, state);
192 private UserDataHolder getSharedModuleData(final Module module) {
193 UserDataHolder dataHolder = mySharedModuleData.get(module);
194 if (dataHolder == null) {
195 dataHolder = new UserDataHolderBase();
196 mySharedModuleData.put(module, dataHolder);
198 return dataHolder;
201 @NotNull
202 public FacetModel getFacetModel(Module module) {
203 final ModifiableFacetModel model = myModels.get(module);
204 if (model != null) {
205 return model;
207 return FacetManager.getInstance(module);
210 public void commitFacets() {
211 for (ModifiableFacetModel model : myModels.values()) {
212 model.commit();
215 for (Map.Entry<Facet, FacetEditorImpl> entry : myEditors.entrySet()) {
216 entry.getValue().onFacetAdded(entry.getKey());
219 myModels.clear();
220 for (Facet facet : myChangedFacets) {
221 Module module = facet.getModule();
222 if (!module.isDisposed()) {
223 module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
226 myChangedFacets.clear();
229 public void resetEditors() {
230 for (FacetEditorImpl editor : myEditors.values()) {
231 editor.reset();
235 public void applyEditors() throws ConfigurationException {
236 for (Map.Entry<Facet, FacetEditorImpl> entry : myEditors.entrySet()) {
237 final FacetEditorImpl editor = entry.getValue();
238 if (editor.isModified()) {
239 myChangedFacets.add(entry.getKey());
241 editor.apply();
245 public boolean isModified() {
246 for (ModifiableFacetModel model : myModels.values()) {
247 if (model.isModified()) {
248 return true;
251 for (FacetEditorImpl editor : myEditors.values()) {
252 if (editor.isModified()) {
253 return true;
256 return false;
259 public FacetTreeModel getTreeModel(Module module) {
260 FacetTreeModel treeModel = myTreeModels.get(module);
261 if (treeModel == null) {
262 treeModel = new FacetTreeModel();
263 myTreeModels.put(module, treeModel);
265 return treeModel;
268 public FacetInfo getFacetInfo(final Facet facet) {
269 return myFacet2Info.get(facet);
272 public Facet getFacet(final FacetInfo facetInfo) {
273 return myInfo2Facet.get(facetInfo);
276 public void disposeEditors() {
277 for (Facet facet : myFacetsToDispose) {
278 Disposer.dispose(facet);
280 myFacetsToDispose.clear();
281 myCreatedFacets.clear();
283 for (FacetEditorImpl editor : myEditors.values()) {
284 editor.disposeUIResources();
286 myProjectData = null;
289 @NotNull
290 public Facet[] getAllFacets(final Module module) {
291 return getFacetModel(module).getAllFacets();
294 @NotNull
295 public <F extends Facet> Collection<F> getFacetsByType(final Module module, final FacetTypeId<F> type) {
296 return getFacetModel(module).getFacetsByType(type);
299 @Nullable
300 public <F extends Facet> F findFacet(final Module module, final FacetTypeId<F> type, final String name) {
301 return getFacetModel(module).findFacet(type, name);
304 public void moduleStateChanged(final ModifiableRootModel moduleRootModel) {
305 Module module = moduleRootModel.getModule();
306 Facet[] allFacets = getAllFacets(module);
307 for (Facet facet : allFacets) {
308 FacetEditorImpl facetEditor = myEditors.get(facet);
309 if (facetEditor != null) {
310 ((FacetEditorContextBase)facetEditor.getContext()).fireModuleRootsChanged(moduleRootModel);
315 private void fireFacetModelChanged(Module module) {
316 for (Facet facet : getAllFacets(module)) {
317 FacetEditorImpl facetEditor = myEditors.get(facet);
318 if (facetEditor != null) {
319 ((FacetEditorContextBase)facetEditor.getContext()).fireFacetModelChanged(module);
324 private UserDataHolder getProjectData() {
325 if (myProjectData == null) {
326 myProjectData = new UserDataHolderBase();
328 return myProjectData;
331 public List<Facet> removeAllFacets(final Module module) {
332 List<Facet> facets = new ArrayList<Facet>();
333 FacetModel facetModel = getOrCreateModifiableModel(module);
334 for (Facet facet : facetModel.getAllFacets()) {
335 if (!myCreatedFacets.contains(facet)) {
336 myFacetsToDispose.add(facet);
338 LOG.assertTrue(facet.getModule().equals(module), module + " expected but " + facet.getModule() + " found");
339 facets.addAll(removeFacet(facet));
341 mySharedModuleData.remove(module);
342 myModels.remove(module);
343 return facets;
346 private class MyProjectConfigurableContext extends ProjectConfigurableContext {
347 private final LibrariesContainer myContainer;
349 public MyProjectConfigurableContext(final Facet facet, final FacetEditorContext parentContext, final ModuleConfigurationState state) {
350 super(facet, ProjectFacetsConfigurator.this.isNewFacet(facet), parentContext, state,
351 ProjectFacetsConfigurator.this.getSharedModuleData(facet.getModule()), getProjectData());
352 myContainer = LibrariesContainerFactory.createContainer(facet.getModule().getProject(), myContext);
355 public LibrariesContainer getContainer() {
356 return myContainer;