package jetbrains.mps.make.facet;
/*Generated by MPS */
import jetbrains.mps.components.CoreComponent;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import java.util.Map;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import java.util.Set;
import jetbrains.mps.baseLanguage.tuples.runtime.Tuples;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import jetbrains.mps.smodel.language.LanguageRegistry;
import jetbrains.mps.baseLanguage.tuples.runtime.MultiTuple;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.smodel.language.LanguageRuntime;
import jetbrains.mps.smodel.runtime.MakeAspectDescriptor;
import jetbrains.mps.internal.collections.runtime.ISelector;
import java.util.Collections;
public class FacetRegistry implements CoreComponent {
private static Logger LOG = LogManager.getLogger(FacetRegistry.class);
private static FacetRegistry INSTANCE;
private Map<IFacet.Name, IFacet> facetMap = MapSequence.fromMap(new HashMap<IFacet.Name, IFacet>());
private Set<Tuples._2<String, IFacet>> facetsForLanguages = SetSequence.fromSet(new HashSet<Tuples._2<String, IFacet>>());
private final LanguageRegistry myLanguageRegistry;
public FacetRegistry(LanguageRegistry languageRegistry) {
// 1. languageRegistry could be null to facilitate unit tests.
// 2. technically, package-local visibility would suffice, however, MPS could not guess it's the same package for two models with same qualified name.
// 3. FIXME In fact, there's not too much reason to pass LanguageRegistry here, we use it to go from namespace in IFacet.Name to SLanguage. IFacet.Name could give SLanguage right away.
myLanguageRegistry = languageRegistry;
}
@Override
public void init() {
INSTANCE = this;
}
@Override
public void dispose() {
INSTANCE = null;
}
@Deprecated
public void register(IFacet facet) {
register(null, facet);
}
public void register(String languageNamespace, IFacet facet) {
if (MapSequence.fromMap(facetMap).containsKey(facet.getName())) {
throw new IllegalArgumentException("already registered");
}
MapSequence.fromMap(facetMap).put(facet.getName(), facet);
SetSequence.fromSet(facetsForLanguages).addElement(MultiTuple.<String,IFacet>from(languageNamespace, facet));
}
public void unregister(final IFacet facet) {
if (!(MapSequence.fromMap(facetMap).containsKey(facet.getName()))) {
throw new IllegalArgumentException("not registered");
}
MapSequence.fromMap(facetMap).removeKey(facet.getName());
facetsForLanguages = SetSequence.fromSetWithValues(new HashSet<Tuples._2<String, IFacet>>(), SetSequence.fromSet(facetsForLanguages).where(new IWhereFilter<Tuples._2<String, IFacet>>() {
public boolean accept(Tuples._2<String, IFacet> it) {
return !(facet.equals(it._1()));
}
}));
}
public IFacet lookup(IFacet.Name fn) {
LanguageRegistry langReg = myLanguageRegistry;
if (langReg != null) {
LanguageRuntime lr = langReg.getLanguage(fn.getNamespace());
if (lr != null) {
IFacetManifest fm = lr.getAspect(MakeAspectDescriptor.class).getManifest();
IFacet fct = fm.lookup(fn);
if (fct != null) {
return fct;
}
}
}
// fallback to the "old" mechanism
LOG.debug("facet not found, loading using deprecated mechanism " + fn);
return MapSequence.fromMap(facetMap).get(fn);
}
public Iterable<IFacet> getFacetsForLanguage(final String languageNamespace) {
return SetSequence.fromSet(facetsForLanguages).where(new IWhereFilter<Tuples._2<String, IFacet>>() {
public boolean accept(Tuples._2<String, IFacet> it) {
return languageNamespace.equals(it._0());
}
}).select(new ISelector<Tuples._2<String, IFacet>, IFacet>() {
public IFacet select(Tuples._2<String, IFacet> it) {
return it._1();
}
});
}
public Map<IFacet.Name, IFacet> allFacets() {
return Collections.unmodifiableMap(facetMap);
}
public static FacetRegistry getInstance() {
if (INSTANCE == null) {
LOG.fatal("not initialized");
throw new IllegalStateException("not initialized");
}
return INSTANCE;
}
}