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