String msg = String.format("Diff is only supported if the node exists in both cases. " +
"Node [%s], fromRev [%s] -> %s, toRev [%s] -> %s",
path, fromRev, from != null, toRev, to != null);
throw new MicroKernelException(msg);
}
JsopWriter w = new JsopStream();
for (String p : from.getPropertyNames()) {
// changed or removed properties
String fromValue = from.getProperty(p);
String toValue = to.getProperty(p);
if (!fromValue.equals(toValue)) {
w.tag('^').key(p);
if (toValue == null) {
w.value(toValue);
} else {
w.encodedValue(toValue).newline();
}
}
}
for (String p : to.getPropertyNames()) {
// added properties
if (from.getProperty(p) == null) {
w.tag('^').key(p).encodedValue(to.getProperty(p)).newline();
}
}
// TODO this does not work well for large child node lists
// use a MongoDB index instead
int max = MANY_CHILDREN_THRESHOLD;
Children fromChildren, toChildren;
fromChildren = nodeStore.getChildren(path, fromRev, max);
toChildren = nodeStore.getChildren(path, toRev, max);
if (!fromChildren.hasMore && !toChildren.hasMore) {
diffFewChildren(w, fromChildren, fromRev, toChildren, toRev);
} else {
if (FAST_DIFF) {
diffManyChildren(w, path, fromRev, toRev);
} else {
max = Integer.MAX_VALUE;
fromChildren = nodeStore.getChildren(path, fromRev, max);
toChildren = nodeStore.getChildren(path, toRev, max);
diffFewChildren(w, fromChildren, fromRev, toChildren, toRev);
}
}
return w.toString();
}