package jetbrains.mps.vcs.changesmanager.tree;
/*Generated by MPS */
import com.intellij.openapi.components.AbstractProjectComponent;
import jetbrains.mps.vcs.diff.changes.ModelChange;
import java.util.Map;
import jetbrains.mps.vcs.changesmanager.tree.features.Feature;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import jetbrains.mps.vcs.changesmanager.CurrentDifferenceRegistry;
import com.intellij.openapi.project.Project;
import jetbrains.mps.project.MPSProject;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import org.jetbrains.mps.openapi.model.SModelReference;
import jetbrains.mps.vcs.diff.changes.AddRootChange;
import jetbrains.mps.vcs.changesmanager.tree.features.NodeFeature;
import jetbrains.mps.smodel.SNodePointer;
import jetbrains.mps.vcs.diff.changes.SetPropertyChange;
import jetbrains.mps.vcs.changesmanager.tree.features.PropertyFeature;
import jetbrains.mps.vcs.diff.changes.SetReferenceChange;
import jetbrains.mps.vcs.changesmanager.tree.features.ReferenceFeature;
import jetbrains.mps.vcs.diff.changes.NodeGroupChange;
import org.jetbrains.mps.openapi.model.SNodeId;
import jetbrains.mps.vcs.changesmanager.tree.features.DeletedChildFeature;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.util.IterableUtil;
import jetbrains.mps.vcs.changesmanager.CurrentDifferenceAdapter;
import jetbrains.mps.ide.project.ProjectHelper;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.IVisitor;
public class FeatureForestMapSupport extends AbstractProjectComponent {
private final FeatureForestMap<ModelChange> myMap;
private Map<ModelChange, Feature[]> myChangeToFeaturesMap = MapSequence.fromMap(new HashMap<ModelChange, Feature[]>());
private CurrentDifferenceRegistry myCurrentDifferenceRegistry;
private FeatureForestMapSupport.MyListener myListener = new FeatureForestMapSupport.MyListener();
public FeatureForestMapSupport(Project project, MPSProject mpsProject, CurrentDifferenceRegistry currentDifferenceRegistry) {
super(project);
myMap = new FeatureForestMap<ModelChange>(mpsProject.getRepository());
myCurrentDifferenceRegistry = currentDifferenceRegistry;
}
@Override
public void initComponent() {
myCurrentDifferenceRegistry.addGlobalDifferenceListener(myListener);
}
@Override
public void disposeComponent() {
myCurrentDifferenceRegistry.removeGlobalDifferenceListener(myListener);
}
@NotNull
public FeatureForestMap<ModelChange> getMap() {
return myMap;
}
/*package*/ static Feature[] getFeaturesForChange(@NotNull ModelChange change) {
List<Feature> result = ListSequence.fromList(new ArrayList<Feature>());
SModelReference modelReference = change.getChangeSet().getNewModel().getReference();
if (change instanceof AddRootChange) {
AddRootChange arc = ((AddRootChange) change);
ListSequence.fromList(result).addElement(new NodeFeature(new SNodePointer(modelReference, arc.getRootId())));
} else if (change instanceof SetPropertyChange) {
SetPropertyChange spc = ((SetPropertyChange) change);
ListSequence.fromList(result).addElement(new PropertyFeature(new SNodePointer(modelReference, spc.getAffectedNodeId()), spc.getPropertyName()));
} else if (change instanceof SetReferenceChange) {
SetReferenceChange src = ((SetReferenceChange) change);
ListSequence.fromList(result).addElement(new ReferenceFeature(new SNodePointer(modelReference, src.getAffectedNodeId()), src.getRole()));
} else if (change instanceof NodeGroupChange) {
NodeGroupChange ngc = ((NodeGroupChange) change);
SNodeId parentId = ngc.getParentNodeId();
int begin = ngc.getResultBegin();
int end = ngc.getResultEnd();
String role = ngc.getRole();
if (begin == end) {
ListSequence.fromList(result).addElement(new DeletedChildFeature(new SNodePointer(modelReference, parentId), role, begin));
} else {
List<SNode> changeChildren = (List<SNode>) IterableUtil.asList(change.getChangeSet().getNewModel().getNode(parentId).getChildren(role));
for (int i = begin; i < end; i++) {
if (i < ListSequence.fromList(changeChildren).count()) {
ListSequence.fromList(result).addElement(new NodeFeature(new SNodePointer(modelReference, ListSequence.fromList(changeChildren).getElement(i).getNodeId())));
}
}
}
}
return ListSequence.fromList(result).toGenericArray(Feature.class);
}
private class MyListener extends CurrentDifferenceAdapter {
public MyListener() {
}
@Override
public void changeAdded(@NotNull final ModelChange change) {
ProjectHelper.getModelAccess(myProject).runReadAction(new Runnable() {
public void run() {
Feature[] features = FeatureForestMapSupport.getFeaturesForChange(change);
MapSequence.fromMap(myChangeToFeaturesMap).put(change, features);
for (Feature f : MapSequence.fromMap(myChangeToFeaturesMap).get(change)) {
myMap.put(f, change);
}
}
});
}
@Override
public void changeRemoved(@NotNull ModelChange change) {
Sequence.fromIterable(Sequence.fromArray(MapSequence.fromMap(myChangeToFeaturesMap).get(change))).visitAll(new IVisitor<Feature>() {
public void visit(Feature f) {
myMap.removeKey(f);
}
});
MapSequence.fromMap(myChangeToFeaturesMap).removeKey(change);
}
}
}