* Processes the input sources and sends the changes to the change sink.
*/
public void run() {
try {
EntityContainerComparator comparator;
EntityContainer fromEntityContainer = null;
EntityContainer toEntityContainer = null;
TimestampSetter timestampSetter;
// Create a comparator for comparing two entities by type and identifier.
comparator = new EntityContainerComparator(new EntityByTypeThenIdComparator());
// Create an object for setting the current timestamp on entities being deleted.
timestampSetter = new TimestampSetter();
// We can't get meaningful data from the initialize data on the
// input streams, so pass empty meta data to the sink and discard
// the input meta data.
fromPostbox.outputInitialize();
toPostbox.outputInitialize();
changeSink.initialize(Collections.<String, Object>emptyMap());
// We continue in the comparison loop while both sources still have data.
while (
(fromEntityContainer != null || fromPostbox.hasNext())
&& (toEntityContainer != null || toPostbox.hasNext())) {
int comparisonResult;
// Get the next input data where required.
if (fromEntityContainer == null) {
fromEntityContainer = fromPostbox.getNext();
}
if (toEntityContainer == null) {
toEntityContainer = toPostbox.getNext();
}
// Compare the two sources.
comparisonResult = comparator.compare(fromEntityContainer, toEntityContainer);
if (comparisonResult < 0) {
// The from entity doesn't exist on the to source therefore
// has been deleted. We don't know when the entity was
// deleted so set the delete time to the current time.
changeSink.process(
new ChangeContainer(
timestampSetter.updateTimestamp(fromEntityContainer),
ChangeAction.Delete));
fromEntityContainer = null;
} else if (comparisonResult > 0) {
// The to entity doesn't exist on the from source therefore has
// been created.
changeSink.process(new ChangeContainer(toEntityContainer, ChangeAction.Create));
toEntityContainer = null;
} else {
// The entity exists on both sources, therefore we must
// compare
// the entities directly. If there is a difference, the
// entity has been modified.
if (!fromEntityContainer.getEntity().equals(toEntityContainer.getEntity())) {
changeSink.process(new ChangeContainer(toEntityContainer, ChangeAction.Modify));
}
fromEntityContainer = null;
toEntityContainer = null;
}