blob: 1006ac40f9b7d3633ce8bcfa8fcbf079bfc7611e [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.facet.impl;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetModel;
import com.intellij.facet.FacetTypeId;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author nik
*/
public abstract class FacetModelBase implements FacetModel {
private volatile Map<FacetTypeId, Collection<Facet>> myType2Facets;
private volatile Map<Pair<Facet, FacetTypeId>, Collection<Facet>> myChildFacets;
private volatile Facet[] mySortedFacets;
@Override
@NotNull
public Facet[] getSortedFacets() {
if (mySortedFacets == null) {
final Facet[] allFacets = getAllFacets();
if (allFacets.length == 0) {
mySortedFacets = Facet.EMPTY_ARRAY;
}
else {
LinkedHashSet<Facet> facets = new LinkedHashSet<Facet>();
for (Facet facet : allFacets) {
addUnderlyingFacets(facets, facet);
}
mySortedFacets = facets.toArray(new Facet[facets.size()]);
}
}
return mySortedFacets;
}
private static void addUnderlyingFacets(final LinkedHashSet<Facet> facets, final Facet facet) {
final Facet underlyingFacet = facet.getUnderlyingFacet();
if (underlyingFacet != null && !facets.contains(facet)) {
addUnderlyingFacets(facets, underlyingFacet);
}
facets.add(facet);
}
@Override
@NotNull
public <F extends Facet> Collection<F> getFacetsByType(@NotNull Facet underlyingFacet, FacetTypeId<F> typeId) {
if (myChildFacets == null) {
MultiValuesMap<Pair<Facet, FacetTypeId>, Facet> children = new MultiValuesMap<Pair<Facet, FacetTypeId>, Facet>();
for (Facet facet : getAllFacets()) {
final Facet underlying = facet.getUnderlyingFacet();
if (underlying != null) {
children.put(Pair.create(underlying, facet.getTypeId()), facet);
}
}
Map<Pair<Facet, FacetTypeId>, Collection<Facet>> childFacets = new HashMap<Pair<Facet, FacetTypeId>, Collection<Facet>>();
for (Pair<Facet, FacetTypeId> pair : children.keySet()) {
final Collection<Facet> facets = children.get(pair);
childFacets.put(pair, Collections.unmodifiableCollection(facets));
}
myChildFacets = childFacets;
}
//noinspection unchecked
final Collection<F> facets = (Collection<F>)myChildFacets.get(new Pair(underlyingFacet, typeId));
return facets != null ? facets : Collections.<F>emptyList();
}
@Override
@NotNull
public String getFacetName(@NotNull Facet facet) {
return facet.getName();
}
@Override
@Nullable
public <F extends Facet> F findFacet(final FacetTypeId<F> type, final String name) {
final Collection<F> fs = getFacetsByType(type);
for (F f : fs) {
if (f.getName().equals(name)) {
return f;
}
}
return null;
}
@Override
@Nullable
public <F extends Facet> F getFacetByType(@NotNull final Facet underlyingFacet, final FacetTypeId<F> typeId) {
final Collection<F> fs = getFacetsByType(underlyingFacet, typeId);
return fs.isEmpty() ? null : fs.iterator().next();
}
@Override
@Nullable
public <F extends Facet> F getFacetByType(FacetTypeId<F> typeId) {
final Collection<F> facets = getFacetsByType(typeId);
return facets.isEmpty() ? null : facets.iterator().next();
}
@Override
@NotNull
public <F extends Facet> Collection<F> getFacetsByType(FacetTypeId<F> typeId) {
if (myType2Facets == null) {
MultiValuesMap<FacetTypeId, Facet> typeToFacets = new MultiValuesMap<FacetTypeId, Facet>();
for (Facet facet : getAllFacets()) {
typeToFacets.put(facet.getTypeId(), facet);
}
Map<FacetTypeId, Collection<Facet>> typeToFacetsCollection = new HashMap<FacetTypeId, Collection<Facet>>();
for (FacetTypeId id : typeToFacets.keySet()) {
final Collection<Facet> facets = typeToFacets.get(id);
typeToFacetsCollection.put(id, Collections.unmodifiableCollection(facets));
}
myType2Facets = typeToFacetsCollection;
}
final Collection<F> facets = (Collection<F>)myType2Facets.get(typeId);
return facets != null ? facets : Collections.<F>emptyList();
}
protected void facetsChanged() {
myChildFacets = null;
myType2Facets = null;
mySortedFacets = null;
}
}