package jetbrains.mps.vcs.diff.changes; /*Generated by MPS */ import jetbrains.mps.vcs.diff.ChangeSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.mps.openapi.model.SNodeId; import org.jetbrains.mps.openapi.model.SModel; import org.jetbrains.mps.openapi.model.SNodeReference; import jetbrains.mps.internal.collections.runtime.Sequence; import jetbrains.mps.internal.collections.runtime.ISelector; import jetbrains.mps.internal.collections.runtime.IVisitor; public abstract class ModelChange { private ChangeSet myChangeSet; private ModelChange myOpposite = null; protected ModelChange(@NotNull ChangeSet changeSet) { myChangeSet = changeSet; } @NotNull public final ChangeSet getChangeSet() { return myChangeSet; } @Nullable public SNodeId getRootId() { return null; } public abstract void apply(@NotNull SModel model, @NotNull NodeCopier nodeCopier); public ModelChange getOppositeChange() { if (myOpposite == null) { myOpposite = createOppositeChange(); myOpposite.myOpposite = this; } return myOpposite; } @NotNull protected abstract ModelChange createOppositeChange(); @NotNull public abstract ChangeType getType(); public boolean isNonConflicting() { // true - change can never conflict with other change and should be ignored if connected change exists (e.g. resolveInfo change) return getMergeHint() != null; } @Nullable public SNodeReference getMergeHint() { return null; } @Override public abstract String toString(); public abstract String getDescription(); public static void rollbackChanges(Iterable<ModelChange> changes) { assert Sequence.fromIterable(changes).isNotEmpty(); final SModel model = Sequence.fromIterable(changes).first().getChangeSet().getNewModel(); final NodeCopier nc = new NodeCopier(model); Iterable<ModelChange> oppositeChanges = Sequence.fromIterable(changes).select(new ISelector<ModelChange, ModelChange>() { public ModelChange select(ModelChange ch) { return ch.getOppositeChange(); } }); for (ModelChange ch : Sequence.fromIterable(oppositeChanges)) { if (ch instanceof NodeGroupChange) { ((NodeGroupChange) ch).prepare(); } } Sequence.fromIterable(oppositeChanges).visitAll(new IVisitor<ModelChange>() { public void visit(ModelChange ch) { ch.apply(model, nc); } }); nc.restoreIds(true); } }