net.fortytwo.flow.diff.Diff Maven / Gradle / Ivy
package net.fortytwo.flow.diff;
import net.fortytwo.flow.Sink;
import net.fortytwo.ripple.RippleException;
import java.util.LinkedList;
// TODO: add a concept of Source
/**
* A two-channel data pipeline which distinguishes between data items "added" and "removed"
*
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class Diff implements DiffSink, DiffSource {
private enum Action {Add, Remove}
private class Change {
public T value;
public Action action;
}
// An order-preserving list of changes.
private final LinkedList changes;
private final Sink plusSink;
private final Sink minusSink;
public Diff() {
changes = new LinkedList();
plusSink = new Sink() {
public void put(final T t) throws RippleException {
Change ch = new Change();
ch.value = t;
ch.action = Action.Add;
changes.addLast(ch);
}
};
minusSink = new Sink() {
public void put(final T t) throws RippleException {
Change ch = new Change();
ch.value = t;
ch.action = Action.Remove;
changes.addLast(ch);
}
};
}
public Sink getPlus() {
return plusSink;
}
public Sink getMinus() {
return minusSink;
}
public void clear() {
changes.clear();
}
public int size() {
return changes.size();
}
public void writeTo(final DiffSink sink) throws RippleException {
Sink otherPlusSink = sink.getPlus();
Sink otherMinusSink = sink.getMinus();
for (Change ch : changes) {
switch (ch.action) {
case Add:
otherPlusSink.put(ch.value);
break;
case Remove:
otherMinusSink.put(ch.value);
break;
default:
// FIXME
System.err.println("unsupported Action: " + ch.action);
}
}
}
}