package jetbrains.mps.vcs.diff; /*Generated by MPS */ import org.jetbrains.mps.openapi.model.SModel; import java.util.List; import jetbrains.mps.vcs.diff.changes.ModelChange; import java.util.concurrent.CopyOnWriteArrayList; import java.util.Map; import org.jetbrains.mps.openapi.model.SNodeId; import jetbrains.mps.internal.collections.runtime.MapSequence; import java.util.HashMap; import jetbrains.mps.internal.collections.runtime.ListSequence; import java.util.ArrayList; import org.jetbrains.annotations.NotNull; import java.util.Collections; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import jetbrains.mps.internal.collections.runtime.ISelector; import jetbrains.mps.internal.collections.runtime.Sequence; import org.jetbrains.annotations.Nullable; import jetbrains.mps.internal.collections.runtime.SetSequence; public class ChangeSetImpl implements ModelChangeSet { private final SModel myOldModel; private final SModel myNewModel; private final List<ModelChange> myModelChanges = new CopyOnWriteArrayList<ModelChange>(); private Map<SNodeId, List<ModelChange>> myRootToChanges = MapSequence.fromMap(new HashMap<SNodeId, List<ModelChange>>()); private List<ModelChange> myMetadataChanges = ListSequence.fromList(new ArrayList<ModelChange>()); private ChangeSetImpl myOppositeChangeSet = null; public ChangeSetImpl(@NotNull SModel oldModel, @NotNull SModel newModel) { myOldModel = oldModel; myNewModel = newModel; } @NotNull @Override public List<ModelChange> getModelChanges() { return Collections.unmodifiableList(myModelChanges); } public void clear() { ListSequence.fromList(myModelChanges).clear(); } @NotNull @Override public <C extends ModelChange> Iterable<C> getModelChanges(final Class<C> changeClass) { return ListSequence.fromList(myModelChanges).where(new IWhereFilter<ModelChange>() { public boolean accept(ModelChange ch) { return changeClass.isInstance(ch); } }).select(new ISelector<ModelChange, C>() { public C select(ModelChange ch) { return (C) ch; } }); } @NotNull @Override public SModel getOldModel() { return myOldModel; } @NotNull @Override public SModel getNewModel() { return myNewModel; } @NotNull @Override public ChangeSet getOppositeChangeSet() { if (myOppositeChangeSet == null) { throw new IllegalStateException("opposite chage set is not built"); } return myOppositeChangeSet; } public void clearOppositeChangeSet() { myOppositeChangeSet = null; } public void buildOppositeChangeSet() { if (myOppositeChangeSet == null) { myOppositeChangeSet = new ChangeSetImpl(myNewModel, myOldModel); myOppositeChangeSet.myOppositeChangeSet = this; ListSequence.fromList(myOppositeChangeSet.myModelChanges).addSequence(ListSequence.fromList(myModelChanges).select(new ISelector<ModelChange, ModelChange>() { public ModelChange select(ModelChange c) { return c.getOppositeChange(); } })); myOppositeChangeSet.fillRootToChange(); } } public void add(@NotNull ModelChange change) { ListSequence.fromList(myModelChanges).addElement(change); if (myOppositeChangeSet != null) { ListSequence.fromList(myOppositeChangeSet.myModelChanges).addElement(change.getOppositeChange()); } } public void remove(@NotNull ModelChange change) { ListSequence.fromList(myModelChanges).removeElement(change); if (myOppositeChangeSet != null) { ListSequence.fromList(myOppositeChangeSet.myModelChanges).removeElement(change.getOppositeChange()); } } public void addAll(Iterable<? extends ModelChange> changes) { ListSequence.fromList(myModelChanges).addSequence(Sequence.fromIterable(changes)); if (myOppositeChangeSet != null) { ListSequence.fromList(myOppositeChangeSet.myModelChanges).addSequence(Sequence.fromIterable(changes).select(new ISelector<ModelChange, ModelChange>() { public ModelChange select(ModelChange c) { return c.getOppositeChange(); } })); } } /*package*/ void fillRootToChange() { MapSequence.fromMap(myRootToChanges).clear(); ListSequence.fromList(myMetadataChanges).clear(); for (ModelChange c : ListSequence.fromList(myModelChanges)) { SNodeId id = c.getRootId(); if (id == null) { ListSequence.fromList(myMetadataChanges).addElement(c); } else { if (!(MapSequence.fromMap(myRootToChanges).containsKey(id))) { MapSequence.fromMap(myRootToChanges).put(id, ListSequence.fromList(new ArrayList<ModelChange>())); } ListSequence.fromList(MapSequence.fromMap(myRootToChanges).get(id)).addElement(c); } } } @Override public Iterable<ModelChange> getChangesForRoot(@Nullable SNodeId rootId) { return (rootId == null ? myMetadataChanges : MapSequence.fromMap(myRootToChanges).get(rootId)); } @Override public Iterable<SNodeId> getAffectedRoots() { return (ListSequence.fromList(myMetadataChanges).isEmpty() ? MapSequence.fromMap(myRootToChanges).keySet() : SetSequence.fromSet(MapSequence.fromMap(myRootToChanges).keySet()).concat(ListSequence.fromList(ListSequence.fromListAndArray(new ArrayList<SNodeId>(), null)))); } }