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; } }