package models.deltaAlgebra;
import java.util.ArrayList;
import java.util.List;
/**
* An open/closed (possibly composed) delta.
*
* @author Nitta
*
*/
public class Delta {
private PrimitiveDelta bottomDelta = null;
private Delta subDelta = null;
public Delta(PrimitiveDelta delta) {
bottomDelta = delta;
}
public Delta(PrimitiveDelta bottomDelta, Delta subDelta) {
this.bottomDelta = bottomDelta;
this.subDelta = subDelta;
}
public ObjectNode getCoordinator() {
if (subDelta == null) return bottomDelta.getCoordinator();
return subDelta.getCoordinator();
}
public List<ReferenceEdge> getPullEdges() {
if (subDelta == null) return bottomDelta.getPullEdges();
List<ReferenceEdge> pullEdges = new ArrayList<>(subDelta.getPullEdges());
pullEdges.addAll(bottomDelta.getPullEdges());
return pullEdges;
}
public List<ReferenceEdge> getPushEdges() {
if (subDelta == null) return bottomDelta.getPushEdges();
List<ReferenceEdge> pushEdges = new ArrayList<>(subDelta.getPushEdges());
pushEdges.addAll(bottomDelta.getPushEdges());
return pushEdges;
}
/**
* binding composition
* (this o delta)
*
* @param delta
* @return this o delta
*/
public Delta combine(PrimitiveDelta delta) {
return new Delta(delta, this);
}
/**
* binding composition
* (this o delta)
*
* @param delta
* @return this o delta
*/
public Delta combine(Delta delta) {
Delta preDelta = this.copy();
for (PrimitiveDelta atomicDelta: delta.split()) {
preDelta = preDelta.combine(atomicDelta);
}
return preDelta;
}
/**
* if this = d1 o d2 o ... o dn
*
* @return [d1, d2, ..., dn]
*/
public List<PrimitiveDelta> split() {
if (subDelta == null) {
List<PrimitiveDelta> atomicDeltaSequence = new ArrayList<>();
atomicDeltaSequence.add(bottomDelta);
return atomicDeltaSequence;
}
List<PrimitiveDelta> atomicDeltaSequence = subDelta.split();
atomicDeltaSequence.add(bottomDelta);
return atomicDeltaSequence;
}
public Delta copy() {
if (subDelta == null) {
return new Delta(bottomDelta.copy());
}
return new Delta(bottomDelta.copy(), subDelta.copy());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || !(o instanceof Delta)) return false;
Delta another = (Delta) o;
return bottomDelta.equals(another.bottomDelta) && ((subDelta == null && another.subDelta == null) || subDelta.equals(another.subDelta));
}
@Override
public int hashCode() {
return bottomDelta.hashCode() + (subDelta == null ? 0 : subDelta.hashCode());
}
public String toString() {
return bottomDelta.toString() + (subDelta == null ? "" : " o " + subDelta.toString());
}
}