IDEADEV-40880: FileOutputStream​.​open
[fedora-idea.git] / java / idea-ui / src / com / intellij / facet / impl / autodetecting / model / ProjectFacetInfoSet.java
blobab3c7ed695b8bc29f8ac1e6e3602ce5ae74782ae
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.
16 package com.intellij.facet.impl.autodetecting.model;
18 import com.intellij.facet.*;
19 import com.intellij.facet.impl.FacetUtil;
20 import com.intellij.facet.pointers.FacetPointersManager;
21 import com.intellij.openapi.Disposable;
22 import com.intellij.openapi.diagnostic.Logger;
23 import com.intellij.openapi.module.Module;
24 import com.intellij.openapi.module.ModuleManager;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.util.InvalidDataException;
27 import com.intellij.openapi.util.JDOMUtil;
28 import com.intellij.openapi.util.WriteExternalException;
29 import com.intellij.openapi.util.io.FileUtil;
30 import com.intellij.util.EventDispatcher;
31 import com.intellij.util.SystemProperties;
32 import com.intellij.util.xmlb.XmlSerializer;
33 import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
34 import com.intellij.util.xmlb.annotations.AbstractCollection;
35 import com.intellij.util.xmlb.annotations.Attribute;
36 import com.intellij.util.xmlb.annotations.Tag;
37 import org.jdom.Document;
38 import org.jdom.Element;
39 import org.jetbrains.annotations.NotNull;
41 import java.io.File;
42 import java.io.IOException;
43 import java.util.*;
45 /**
46 * @author nik
48 public class ProjectFacetInfoSet extends FacetInfoSet<Module> {
49 private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet");
50 private final Map<Facet, FacetInfoBackedByFacet> myFacetInfos = new HashMap<Facet, FacetInfoBackedByFacet>();
51 private final EventDispatcher<DetectedFacetListener> myDispatcher = EventDispatcher.create(DetectedFacetListener.class);
52 private int myNextId;
53 private final Project myProject;
55 public ProjectFacetInfoSet(Project project, Disposable parentDisposable) {
56 myProject = project;
57 ProjectWideFacetListenersRegistry.getInstance(project).registerListener(new MyProjectWideFacetAdapter(), parentDisposable);
60 public FacetInfoBackedByFacet getOrCreateInfo(@NotNull Facet facet) {
61 FacetInfoBackedByFacet info = myFacetInfos.get(facet);
62 if (info == null) {
63 info = new FacetInfoBackedByFacet(facet, this);
64 myFacetInfos.put(facet, info);
66 return info;
69 public void addFacetInfo(@NotNull final FacetInfo2<Module> facetInfo) {
70 super.addFacetInfo(facetInfo);
71 if (facetInfo instanceof DetectedFacetInfo) {
72 myDispatcher.getMulticaster().facetDetected((DetectedFacetInfo<Module>)facetInfo);
76 public void removeFacetInfo(@NotNull final FacetInfo2<Module> facetInfo) {
77 super.removeFacetInfo(facetInfo);
78 if (facetInfo instanceof DetectedFacetInfo) {
79 myDispatcher.getMulticaster().facetRemoved((DetectedFacetInfo<Module>)facetInfo);
83 public void loadDetectedFacets(@NotNull File file) {
84 if (!file.exists()) return;
86 FacetTypeRegistry facetTypeRegistry = FacetTypeRegistry.getInstance();
87 ModuleManager moduleManager = ModuleManager.getInstance(myProject);
89 Document document;
90 try {
91 document = JDOMUtil.loadDocument(file);
93 catch (Exception e) {
94 LOG.info(e);
95 return;
98 DetectedFacetsBean detectedFacetsBean = XmlSerializer.deserialize(document, DetectedFacetsBean.class);
99 if (detectedFacetsBean == null) return;
101 for (DetectedFacetBean facetBean : detectedFacetsBean.myFacets) {
102 FacetType type = facetTypeRegistry.findFacetType(facetBean.myTypeId);
103 if (type == null) {
104 LOG.info("facet type '" + facetBean.myTypeId + " not found");
105 continue;
107 Module module = moduleManager.findModuleByName(facetBean.myModuleName);
108 if (module == null) {
109 LOG.info("module '" + facetBean.myModuleName + "' not found");
110 continue;
113 FacetInfo2<Module> underlyingFacet = null;
114 String underlyingId = facetBean.myUnderlyingId;
115 if (underlyingId != null) {
116 if (underlyingId.startsWith("/")) {
117 underlyingFacet = findById(Integer.parseInt(underlyingId.substring(1)));
119 else {
120 Facet facet = FacetPointersManager.getInstance(myProject).create(underlyingId).getFacet();
121 underlyingFacet = facet != null ? getOrCreateInfo(facet) : null;
124 FacetConfiguration configuration = type.createDefaultConfiguration();
125 try {
126 FacetUtil.loadFacetConfiguration(configuration, facetBean.myConfiguration);
128 catch (InvalidDataException e) {
129 LOG.info(e);
130 continue;
133 int id = facetBean.myId;
134 myNextId = Math.max(myNextId, id + 1);
135 addFacetInfo(new DetectedFacetInfoImpl<Module>(facetBean.myFacetName, configuration, type, module, underlyingFacet, null, id,
136 facetBean.myDetectorId));
140 public void saveDetectedFacets(File file) {
141 DetectedFacetsBean facetsBean = new DetectedFacetsBean();
142 Collection<DetectedFacetInfo<Module>> facets = getAllDetectedFacets();
143 Set<DetectedFacetInfo<Module>> added = new HashSet<DetectedFacetInfo<Module>>();
144 for (DetectedFacetInfo<Module> facet : facets) {
145 addFacetBean(facet, facetsBean, added);
148 Element element = XmlSerializer.serialize(facetsBean, new SkipDefaultValuesSerializationFilters());
149 try {
150 FileUtil.delete(file);
151 JDOMUtil.writeDocument(new Document(element), file, SystemProperties.getLineSeparator());
153 catch (IOException e) {
154 LOG.info(e);
158 private static boolean addFacetBean(final DetectedFacetInfo<Module> facet, final DetectedFacetsBean facetsBean,
159 final Set<DetectedFacetInfo<Module>> added) {
160 if (!added.add(facet)) {
161 return true;
164 FacetInfo2<Module> underlyingInfo = facet.getUnderlyingFacetInfo();
165 if (underlyingInfo instanceof DetectedFacetInfo && !addFacetBean((DetectedFacetInfo<Module>)underlyingInfo, facetsBean, added)) {
166 return false;
169 try {
170 final Element configuration = FacetUtil.saveFacetConfiguration(facet.getConfiguration());
171 final String underlyingId;
172 if (underlyingInfo instanceof FacetInfoBackedByFacet) {
173 underlyingId = FacetPointersManager.constructId(((FacetInfoBackedByFacet)underlyingInfo).getFacet());
175 else {
176 underlyingId = underlyingInfo != null ? "/" + ((DetectedFacetInfo)underlyingInfo).getId() : null;
178 DetectedFacetBean facetBean = new DetectedFacetBean(facet.getId(), facet.getFacetName(), facet.getModule().getName(), configuration,
179 facet.getFacetType().getStringId(), underlyingId, facet.getDetectorId());
180 facetsBean.myFacets.add(facetBean);
181 return true;
183 catch (WriteExternalException e) {
184 LOG.info(e);
185 return false;
189 public void addListener(@NotNull DetectedFacetListener listener) {
190 myDispatcher.addListener(listener);
193 public <C extends FacetConfiguration, F extends Facet<C>> DetectedFacetInfo<Module> createInfo(final Module module,
194 final String url, final FacetInfo2<Module> underlyingFacet,
195 final C detectedConfiguration,
196 final String name,
197 final FacetType<F, C> facetType,
198 final String detectorId) {
199 return new DetectedFacetInfoImpl<Module>(name, detectedConfiguration, facetType, module, underlyingFacet, url,
200 generateId(), detectorId);
203 private int generateId() {
204 return myNextId++;
207 private class MyProjectWideFacetAdapter extends ProjectWideFacetAdapter<Facet> {
208 public void facetAdded(final Facet facet) {
209 addFacetInfo(getOrCreateInfo(facet));
212 public void facetRemoved(final Facet facet) {
213 FacetInfoBackedByFacet detected = myFacetInfos.remove(facet);
214 if (detected != null) {
215 removeFacetInfo(detected);
220 public static interface DetectedFacetListener extends EventListener {
221 void facetDetected(final DetectedFacetInfo<Module> info);
222 void facetRemoved(DetectedFacetInfo<Module> info);
226 public static class DetectedFacetsBean {
227 @Tag("facets")
228 @AbstractCollection(surroundWithTag = false)
229 public List<DetectedFacetBean> myFacets = new ArrayList<DetectedFacetBean>();
232 @Tag("facet")
233 public static class DetectedFacetBean {
234 @Attribute("type")
235 public String myTypeId;
237 @Attribute("facet-name")
238 public String myFacetName;
240 @Attribute("id")
241 public int myId;
243 @Tag("configuration")
244 public Element myConfiguration;
246 @Attribute("underlying-id")
247 public String myUnderlyingId;
249 @Attribute("module-name")
250 public String myModuleName;
252 @Attribute("detector-id")
253 public String myDetectorId;
255 public DetectedFacetBean() {
258 public DetectedFacetBean(final int id, final String facetName, final String moduleName, final Element configuration,
259 final String typeId, final String underlyingId, String detectorId) {
260 myId = id;
261 myFacetName = facetName;
262 myConfiguration = configuration;
263 myTypeId = typeId;
264 myModuleName = moduleName;
265 myUnderlyingId = underlyingId;
266 myDetectorId = detectorId;