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