package jetbrains.mps.datatransfer;
/*Generated by MPS */
import jetbrains.mps.smodel.language.LanguageRegistryListener;
import jetbrains.mps.smodel.language.LanguageRegistry;
import java.util.Map;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.openapi.actions.descriptor.CopyPreProcessor;
import jetbrains.mps.openapi.actions.descriptor.PastePostProcessor;
import jetbrains.mps.openapi.actions.descriptor.PasteWrapper;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import jetbrains.mps.smodel.language.LanguageRuntime;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import java.util.Iterator;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.internal.collections.runtime.CollectionSequence;
import jetbrains.mps.openapi.actions.descriptor.ActionAspectDescriptor;
public final class DataTransferManager implements LanguageRegistryListener {
/**
* TODO In fact, it is an editor component. When editor components will be introduced, implement initialization in proper way.
*/
private static DataTransferManager INSTANCE = new DataTransferManager(LanguageRegistry.getInstance());
private LanguageRegistry myLanguageRegistry;
private final Map<SAbstractConcept, CopyPreProcessor> myCopyPreProcessors;
private final Map<SAbstractConcept, PastePostProcessor> myPastePostProcessors;
private final Map<SAbstractConcept, Map<SAbstractConcept, PasteWrapper>> myPasteWrappers;
private boolean myLoaded;
public DataTransferManager(LanguageRegistry languageRegistry) {
myLanguageRegistry = languageRegistry;
myCopyPreProcessors = MapSequence.fromMap(new HashMap<SAbstractConcept, CopyPreProcessor>());
myPastePostProcessors = MapSequence.fromMap(new HashMap<SAbstractConcept, PastePostProcessor>());
myPasteWrappers = MapSequence.fromMap(new HashMap<SAbstractConcept, Map<SAbstractConcept, PasteWrapper>>());
myLoaded = false;
languageRegistry.addRegistryListener(this);
}
public static DataTransferManager getInstance() {
return INSTANCE;
}
@Override
public void afterLanguagesLoaded(Iterable<LanguageRuntime> iterable) {
// nop. cache will be builded lazily
}
@Override
public void beforeLanguagesUnloaded(Iterable<LanguageRuntime> iterable) {
myLoaded = false;
MapSequence.fromMap(myCopyPreProcessors).clear();
MapSequence.fromMap(myPastePostProcessors).clear();
MapSequence.fromMap(myPasteWrappers).clear();
}
public void preProcessNode(SNode copy, SNode original) {
CopyPreProcessor preProcessor = getCopyPreProcessor(SNodeOperations.getConcept(copy));
if (preProcessor != null) {
preProcessor.preProcessNode(copy, original);
return;
}
Iterator<SNode> originalChildrenIterator = ListSequence.fromList(SNodeOperations.getChildren(original)).iterator();
Iterator<SNode> copyChildrenIterator = ListSequence.fromList(SNodeOperations.getChildren(copy)).iterator();
while (originalChildrenIterator.hasNext()) {
preProcessNode(copyChildrenIterator.next(), originalChildrenIterator.next());
}
}
public void postProcessNode(SNode pastedNode) {
PastePostProcessor postProcessor = getPastePostProcessor(SNodeOperations.getConcept(pastedNode));
if (postProcessor != null) {
postProcessor.postProcessNode(pastedNode);
return;
}
for (SNode pastedChild : ListSequence.fromList(SNodeOperations.getChildren(pastedNode))) {
postProcessNode(pastedChild);
}
}
public boolean canWrapInto(SNode node, SAbstractConcept targetConcept) {
return getPasteWrapper(SNodeOperations.getConcept(node), targetConcept) != null;
}
public SNode wrapInto(SNode node, SAbstractConcept targetConcept) {
PasteWrapper pasteWrapper = getPasteWrapper(SNodeOperations.getConcept(node), targetConcept);
if (pasteWrapper != null) {
SNode newNode = pasteWrapper.wrap(node);
SNodeOperations.deleteNode(newNode);
return newNode;
}
return null;
}
private CopyPreProcessor getCopyPreProcessor(SAbstractConcept concept) {
buildCache();
return MapSequence.fromMap(myCopyPreProcessors).get(concept);
}
private PastePostProcessor getPastePostProcessor(SAbstractConcept concept) {
buildCache();
return MapSequence.fromMap(myPastePostProcessors).get(concept);
}
private PasteWrapper getPasteWrapper(SAbstractConcept source, SAbstractConcept target) {
buildCache();
Map<SAbstractConcept, PasteWrapper> wrappers = MapSequence.fromMap(myPasteWrappers).get(target);
for (SAbstractConcept src : ListSequence.fromList(SConceptOperations.getAllSuperConcepts(source, true))) {
PasteWrapper pasteWrapper = MapSequence.fromMap(wrappers).get(src);
if (pasteWrapper != null) {
return pasteWrapper;
}
}
return null;
}
public void buildCache() {
if (myLoaded) {
return;
}
myLoaded = true;
for (LanguageRuntime lang : CollectionSequence.fromCollection(myLanguageRegistry.getAvailableLanguages())) {
ActionAspectDescriptor actionAscpect = lang.getAspect(ActionAspectDescriptor.class);
if (actionAscpect == null) {
continue;
}
for (CopyPreProcessor copyPreProcessor : CollectionSequence.fromCollection(actionAscpect.getCopyPreProcessors())) {
MapSequence.fromMap(myCopyPreProcessors).put(copyPreProcessor.getApplicableConcept(), copyPreProcessor);
}
for (PastePostProcessor pastePostProcessor : CollectionSequence.fromCollection(actionAscpect.getPastePostProcessors())) {
MapSequence.fromMap(myPastePostProcessors).put(pastePostProcessor.getApplicableConcept(), pastePostProcessor);
}
for (PasteWrapper pasteWrapper : CollectionSequence.fromCollection(actionAscpect.getPasteWrappers())) {
if (!(MapSequence.fromMap(myPasteWrappers).containsKey(pasteWrapper.getTargetConcept()))) {
MapSequence.fromMap(myPasteWrappers).put(pasteWrapper.getTargetConcept(), MapSequence.fromMap(new HashMap<SAbstractConcept, PasteWrapper>()));
}
MapSequence.fromMap(MapSequence.fromMap(myPasteWrappers).get(pasteWrapper.getTargetConcept())).put(pasteWrapper.getSourceConcept(), pasteWrapper);
}
}
}
}