package jetbrains.mps.editor.runtime.impl;
/*Generated by MPS */
import com.intellij.openapi.components.ApplicationComponent;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import java.util.Map;
import jetbrains.mps.smodel.adapter.ids.SLanguageId;
import java.util.List;
import jetbrains.mps.openapi.editor.cells.KeyMap;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import jetbrains.mps.smodel.language.LanguageRegistry;
import jetbrains.mps.ide.MPSCoreComponents;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.language.SLanguage;
import jetbrains.mps.smodel.adapter.ids.MetaIdHelper;
import org.jetbrains.mps.openapi.module.SModule;
import java.util.Collections;
import jetbrains.mps.smodel.language.LanguageRuntime;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModuleOperations;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId;
import org.apache.log4j.Level;
import com.intellij.openapi.application.ApplicationManager;
import jetbrains.mps.smodel.language.LanguageRegistryListener;
public class LanguagesKeymapManager implements ApplicationComponent {
private static final Logger LOG = LogManager.getLogger(LanguagesKeymapManager.class);
private final Map<SLanguageId, List<KeyMap>> myLanguagesToKeyMaps = MapSequence.fromMap(new HashMap<SLanguageId, List<KeyMap>>());
private final LanguagesKeymapManager.LanguageLoadListener myListener = new LanguagesKeymapManager.LanguageLoadListener();
private final LanguageRegistry myLanguageRegistry;
public LanguagesKeymapManager(MPSCoreComponents coreComponents) {
myLanguageRegistry = coreComponents.getPlatform().findComponent(LanguageRegistry.class);
}
public List<KeyMap> getKeyMapsForLanguage(@NotNull SLanguage l) {
SLanguageId languageId = MetaIdHelper.getLanguage(l);
if (!(MapSequence.fromMap(myLanguagesToKeyMaps).containsKey(languageId))) {
// FIXME this is a hack, until we expose KeyMaps as part of editor aspect (or standalone aspect), we need name from CellKeyMapDeclaration node
SModule sourceModule = l.getSourceModule();
if (sourceModule == null) {
return Collections.<KeyMap>emptyList();
}
LanguageRuntime languageRuntime = myLanguageRegistry.getLanguage(languageId);
if (languageRuntime == null) {
return Collections.<KeyMap>emptyList();
}
MapSequence.fromMap(myLanguagesToKeyMaps).put(languageId, loadLanguageKeyMaps(languageRuntime, sourceModule));
}
return MapSequence.fromMap(myLanguagesToKeyMaps).get(languageId);
}
@Override
public void initComponent() {
myLanguageRegistry.addRegistryListener(myListener);
}
@Override
public void disposeComponent() {
myLanguageRegistry.removeRegistryListener(myListener);
}
@NonNls
@NotNull
@Override
public String getComponentName() {
return "Language KeyMap Manager";
}
private void clearCaches() {
MapSequence.fromMap(myLanguagesToKeyMaps).clear();
}
private List<KeyMap> loadLanguageKeyMaps(LanguageRuntime languageRuntime, SModule languageSource) {
SModel editorModelDescriptor = SModuleOperations.getAspect(languageSource, "editor");
SModel editorModel = (editorModelDescriptor != null ? editorModelDescriptor : null);
if (editorModel == null) {
return Collections.<KeyMap>emptyList();
}
List<SNode> declarations = SModelOperations.roots(editorModel, MetaAdapterFactory.getConcept(0x18bc659203a64e29L, 0xa83a7ff23bde13baL, 0xfbc216b31bL, "jetbrains.mps.lang.editor.structure.CellKeyMapDeclaration"));
if (ListSequence.fromList(declarations).isEmpty()) {
return Collections.<KeyMap>emptyList();
}
List<KeyMap> keyMaps = ListSequence.fromList(new ArrayList<KeyMap>());
for (SNode keyMapDeclaration : ListSequence.fromList(declarations)) {
try {
Class<KeyMap> keyMapClass = (Class<KeyMap>) languageRuntime.getClass().getClassLoader().loadClass(((String) BHReflection.invoke(keyMapDeclaration, SMethodTrimmedId.create("getFqName", null, "hEwIO9y"))));
KeyMap keyMap = keyMapClass.newInstance();
if (keyMap.isApplicableToEveryModel()) {
ListSequence.fromList(keyMaps).addElement(keyMap);
}
} catch (ClassNotFoundException ex) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("Failed to instantiate keymap", ex);
}
} catch (InstantiationException e) {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("Failed to instantiate keymap", e);
}
} catch (IllegalAccessException e) {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("Failed to instantiate keymap", e);
}
}
}
return (ListSequence.fromList(keyMaps).isEmpty() ? Collections.<KeyMap>emptyList() : keyMaps);
}
/*package*/ void unregisterLanguageKeyMaps(LanguageRuntime lr) {
MapSequence.fromMap(myLanguagesToKeyMaps).removeKey(lr.getId());
}
public static LanguagesKeymapManager getInstance() {
return ApplicationManager.getApplication().getComponent(LanguagesKeymapManager.class);
}
private class LanguageLoadListener implements LanguageRegistryListener {
/*package*/ LanguageLoadListener() {
}
@Override
public void afterLanguagesLoaded(Iterable<LanguageRuntime> iterable) {
}
@Override
public void beforeLanguagesUnloaded(Iterable<LanguageRuntime> iterable) {
for (LanguageRuntime lr : iterable) {
unregisterLanguageKeyMaps(lr);
}
}
}
}