[platform] get rid of some raw types in facets API and impl
[idea/community.git] / platform / lang-impl / src / com / intellij / facet / impl / FacetModelBase.java
1 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2
3 package com.intellij.facet.impl;
4
5 import com.intellij.facet.Facet;
6 import com.intellij.facet.FacetModel;
7 import com.intellij.facet.FacetTypeId;
8 import com.intellij.openapi.util.MultiValuesMap;
9 import com.intellij.openapi.util.Pair;
10 import org.jetbrains.annotations.NotNull;
11 import org.jetbrains.annotations.Nullable;
12
13 import java.util.*;
14
15 public abstract class FacetModelBase implements FacetModel {
16   private volatile Map<FacetTypeId<?>, Collection<Facet<?>>> myType2Facets;
17   private volatile Map<Pair<Facet<?>, FacetTypeId<?>>, Collection<Facet<?>>> myChildFacets;
18   private volatile Facet<?>[] mySortedFacets;
19
20   @Override
21   public Facet<?> @NotNull [] getSortedFacets() {
22     if (mySortedFacets == null) {
23       final Facet<?>[] allFacets = getAllFacets();
24       if (allFacets.length == 0) {
25         mySortedFacets = Facet.EMPTY_ARRAY;
26       }
27       else {
28         LinkedHashSet<Facet<?>> facets = new LinkedHashSet<>();
29         for (Facet<?> facet : allFacets) {
30           addUnderlyingFacets(facets, facet);
31         }
32         mySortedFacets = facets.toArray(Facet.EMPTY_ARRAY);
33       }
34     }
35     return mySortedFacets;
36   }
37
38   private static void addUnderlyingFacets(final LinkedHashSet<? super Facet<?>> facets, final Facet<?> facet) {
39     final Facet<?> underlyingFacet = facet.getUnderlyingFacet();
40     if (underlyingFacet != null && !facets.contains(facet)) {
41       addUnderlyingFacets(facets, underlyingFacet);
42     }
43     facets.add(facet);
44   }
45
46   @Override
47   @NotNull
48   public <F extends Facet<?>> Collection<F> getFacetsByType(@NotNull Facet<?> underlyingFacet, FacetTypeId<F> typeId) {
49     if (myChildFacets == null) {
50       MultiValuesMap<Pair<Facet<?>, FacetTypeId<?>>, Facet<?>> children = new MultiValuesMap<>();
51       for (Facet<?> facet : getAllFacets()) {
52         final Facet<?> underlying = facet.getUnderlyingFacet();
53         if (underlying != null) {
54           children.put(new Pair<>(underlying,  facet.getTypeId()), facet);
55         }
56       }
57
58       Map<Pair<Facet<?>, FacetTypeId<?>>, Collection<Facet<?>>> childFacets = new HashMap<>();
59       for (Pair<Facet<?>, FacetTypeId<?>> pair : children.keySet()) {
60         final Collection<Facet<?>> facets = children.get(pair);
61         childFacets.put(pair, Collections.unmodifiableCollection(facets));
62       }
63       myChildFacets = childFacets;
64     }
65     //noinspection unchecked
66     final Collection<F> facets = (Collection<F>)myChildFacets.get(new Pair<>(underlyingFacet, typeId));
67     return facets != null ? facets : Collections.emptyList();
68   }
69
70   @Override
71   @NotNull
72   public String getFacetName(@NotNull Facet<?> facet) {
73     return facet.getName();
74   }
75
76   @Override
77   @Nullable
78   public <F extends Facet<?>> F findFacet(final FacetTypeId<F> type, final String name) {
79     final Collection<F> fs = getFacetsByType(type);
80     for (F f : fs) {
81       if (f.getName().equals(name)) {
82         return f;
83       }
84     }
85     return null;
86   }
87
88   @Override
89   @Nullable
90   public <F extends Facet<?>> F getFacetByType(@NotNull final Facet<?> underlyingFacet, final FacetTypeId<F> typeId) {
91     final Collection<F> fs = getFacetsByType(underlyingFacet, typeId);
92     return fs.isEmpty() ? null : fs.iterator().next();
93   }
94
95   @Override
96   @Nullable
97   public <F extends Facet<?>> F getFacetByType(FacetTypeId<F> typeId) {
98     final Collection<F> facets = getFacetsByType(typeId);
99     return facets.isEmpty() ? null : facets.iterator().next();
100   }
101
102   @Override
103   @NotNull
104   public <F extends Facet<?>> Collection<F> getFacetsByType(FacetTypeId<F> typeId) {
105     if (myType2Facets == null) {
106       MultiValuesMap<FacetTypeId<?>, Facet<?>> typeToFacets = new MultiValuesMap<>();
107       for (Facet<?> facet : getAllFacets()) {
108         typeToFacets.put(facet.getTypeId(), facet);
109       }
110       Map<FacetTypeId<?>, Collection<Facet<?>>> typeToFacetsCollection = new HashMap<>();
111       for (FacetTypeId<?> id : typeToFacets.keySet()) {
112         final Collection<Facet<?>> facets = typeToFacets.get(id);
113         typeToFacetsCollection.put(id, Collections.unmodifiableCollection(facets));
114       }
115       myType2Facets = typeToFacetsCollection;
116     }
117
118     final Collection<F> facets = (Collection<F>)myType2Facets.get(typeId);
119     return facets != null ? facets : Collections.emptyList();
120   }
121
122   protected void facetsChanged() {
123     myChildFacets = null;
124     myType2Facets = null;
125     mySortedFacets = null;
126   }
127 }