1 package com
.intellij
.util
.xml
.model
.impl
;
3 import com
.intellij
.openapi
.project
.Project
;
4 import com
.intellij
.openapi
.util
.UserDataHolder
;
5 import com
.intellij
.psi
.PsiElement
;
6 import com
.intellij
.psi
.util
.CachedValueProvider
;
7 import com
.intellij
.psi
.xml
.XmlFile
;
8 import com
.intellij
.util
.containers
.ContainerUtil
;
9 import com
.intellij
.util
.xml
.DomElement
;
10 import com
.intellij
.util
.xml
.DomFileElement
;
11 import com
.intellij
.util
.xml
.DomManager
;
12 import com
.intellij
.util
.xml
.ModelMerger
;
13 import com
.intellij
.util
.xml
.model
.DomModel
;
14 import com
.intellij
.util
.xml
.model
.DomModelCache
;
15 import com
.intellij
.util
.xml
.model
.MultipleDomModelFactory
;
16 import org
.jetbrains
.annotations
.NonNls
;
17 import org
.jetbrains
.annotations
.NotNull
;
18 import org
.jetbrains
.annotations
.Nullable
;
23 * User: Sergey.Vasiliev
25 public abstract class CachedMultipleDomModelFactory
<Scope
extends UserDataHolder
, T
extends DomElement
, M
extends DomModel
<T
>, C
extends PsiElement
>
26 extends DomModelFactoryHelper
<T
>
27 implements CachedDomModelFactory
<T
,M
,Scope
>, MultipleDomModelFactory
<Scope
,T
,M
> {
29 private final DomModelCache
<M
, Scope
> myCombinedModelCache
;
30 private final DomModelCache
<List
<M
>, Scope
> myAllModelsCache
;
33 protected CachedMultipleDomModelFactory(@NotNull Class
<T
> aClass
,
34 @NotNull ModelMerger modelMerger
,
35 final Project project
,
36 @NonNls String name
) {
37 super(aClass
,modelMerger
);
39 myCombinedModelCache
= new DomModelCache
<M
, Scope
>(project
, name
+ " combined model") {
41 protected CachedValueProvider
.Result
<M
> computeValue(@NotNull final Scope scope
) {
42 final M combinedModel
= computeCombinedModel(scope
);
43 return new CachedValueProvider
.Result
<M
>(combinedModel
, computeDependencies(combinedModel
, scope
));
47 myAllModelsCache
= new DomModelCache
<List
<M
>, Scope
>(project
, name
+ " models list") {
49 protected CachedValueProvider
.Result
<List
<M
>> computeValue(@NotNull final Scope scope
) {
50 final List
<M
> models
= computeAllModels(scope
);
51 return new CachedValueProvider
.Result
<List
<M
>>(models
, computeDependencies(null, scope
));
57 public abstract M
getModel(@NotNull C context
);
60 public List
<M
> getAllModels(@NotNull Scope scope
) {
62 final List
<M
> models
= myAllModelsCache
.getCachedValue(scope
);
64 return Collections
.emptyList();
72 protected abstract List
<M
> computeAllModels(@NotNull Scope scope
);
75 public M
getCombinedModel(@Nullable Scope scope
) {
79 return myCombinedModelCache
.getCachedValue(scope
);
83 protected M
computeCombinedModel(@NotNull Scope scope
) {
84 final List
<M
> models
= getAllModels(scope
);
85 switch (models
.size()) {
91 final Set
<XmlFile
> configFiles
= new LinkedHashSet
<XmlFile
>();
92 final LinkedHashSet
<DomFileElement
<T
>> list
= new LinkedHashSet
<DomFileElement
<T
>>(models
.size());
93 for (M model
: models
) {
94 final Set
<XmlFile
> files
= model
.getConfigFiles();
95 for (XmlFile file
: files
) {
96 ContainerUtil
.addIfNotNull(getDomRoot(file
), list
);
98 configFiles
.addAll(files
);
100 final DomFileElement
<T
> mergedModel
= getModelMerger().mergeModels(DomFileElement
.class, list
);
101 final M firstModel
= models
.get(0);
102 return createCombinedModel(configFiles
, mergedModel
, firstModel
, scope
);
106 * Factory method to create combined model for given module.
107 * Used by {@link #computeCombinedModel(com.intellij.openapi.module.Module)}.
109 * @param configFiles file set including all files for all models returned by {@link #getAllModels(com.intellij.openapi.module.Module)}.
110 * @param mergedModel merged model for all models returned by {@link #getAllModels(com.intellij.openapi.module.Module)}.
111 * @param firstModel the first model returned by {@link #getAllModels(com.intellij.openapi.module.Module)}.
113 * @return combined model.
115 protected abstract M
createCombinedModel(Set
<XmlFile
> configFiles
, DomFileElement
<T
> mergedModel
, M firstModel
, final Scope scope
);
118 public Set
<XmlFile
> getConfigFiles(@Nullable C context
) {
119 if (context
== null) {
120 return Collections
.emptySet();
122 final M model
= getModel(context
);
124 return Collections
.emptySet();
127 return model
.getConfigFiles();
132 public Set
<XmlFile
> getAllConfigFiles(@NotNull Scope scope
) {
133 final HashSet
<XmlFile
> xmlFiles
= new HashSet
<XmlFile
>();
134 for (M model
: getAllModels(scope
)) {
135 xmlFiles
.addAll(model
.getConfigFiles());
140 public List
<DomFileElement
<T
>> getFileElements(M model
) {
141 final ArrayList
<DomFileElement
<T
>> list
= new ArrayList
<DomFileElement
<T
>>(model
.getConfigFiles().size());
142 for (XmlFile configFile
: model
.getConfigFiles()) {
143 final DomFileElement
<T
> element
= DomManager
.getDomManager(configFile
.getProject()).getFileElement(configFile
, myClass
);
144 if (element
!= null) {