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