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
;
42 import java
.io
.IOException
;
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);
53 private final Project myProject
;
55 public ProjectFacetInfoSet(Project project
, Disposable parentDisposable
) {
57 ProjectWideFacetListenersRegistry
.getInstance(project
).registerListener(new MyProjectWideFacetAdapter(), parentDisposable
);
60 public FacetInfoBackedByFacet
getOrCreateInfo(@NotNull Facet facet
) {
61 FacetInfoBackedByFacet info
= myFacetInfos
.get(facet
);
63 info
= new FacetInfoBackedByFacet(facet
, this);
64 myFacetInfos
.put(facet
, 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
);
91 document
= JDOMUtil
.loadDocument(file
);
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
);
104 LOG
.info("facet type '" + facetBean
.myTypeId
+ " not found");
107 Module module
= moduleManager
.findModuleByName(facetBean
.myModuleName
);
108 if (module
== null) {
109 LOG
.info("module '" + facetBean
.myModuleName
+ "' not found");
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)));
120 Facet facet
= FacetPointersManager
.getInstance(myProject
).create(underlyingId
).getFacet();
121 underlyingFacet
= facet
!= null ?
getOrCreateInfo(facet
) : null;
124 FacetConfiguration configuration
= type
.createDefaultConfiguration();
126 FacetUtil
.loadFacetConfiguration(configuration
, facetBean
.myConfiguration
);
128 catch (InvalidDataException e
) {
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());
150 FileUtil
.delete(file
);
151 JDOMUtil
.writeDocument(new Document(element
), file
, SystemProperties
.getLineSeparator());
153 catch (IOException e
) {
158 private static boolean addFacetBean(final DetectedFacetInfo
<Module
> facet
, final DetectedFacetsBean facetsBean
,
159 final Set
<DetectedFacetInfo
<Module
>> added
) {
160 if (!added
.add(facet
)) {
164 FacetInfo2
<Module
> underlyingInfo
= facet
.getUnderlyingFacetInfo();
165 if (underlyingInfo
instanceof DetectedFacetInfo
&& !addFacetBean((DetectedFacetInfo
<Module
>)underlyingInfo
, facetsBean
, added
)) {
170 final Element configuration
= FacetUtil
.saveFacetConfiguration(facet
.getConfiguration());
171 final String underlyingId
;
172 if (underlyingInfo
instanceof FacetInfoBackedByFacet
) {
173 underlyingId
= FacetPointersManager
.constructId(((FacetInfoBackedByFacet
)underlyingInfo
).getFacet());
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
);
183 catch (WriteExternalException e
) {
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
,
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() {
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
{
228 @AbstractCollection(surroundWithTag
= false)
229 public List
<DetectedFacetBean
> myFacets
= new ArrayList
<DetectedFacetBean
>();
233 public static class DetectedFacetBean
{
235 public String myTypeId
;
237 @Attribute("facet-name")
238 public String myFacetName
;
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
) {
261 myFacetName
= facetName
;
262 myConfiguration
= configuration
;
264 myModuleName
= moduleName
;
265 myUnderlyingId
= underlyingId
;
266 myDetectorId
= detectorId
;