public void handle(AsyncResult<JsonObject> ar) {
if (ar.failed()) {
callback.handle(ar);
return;
}
final DocumentBridge snapshot = createSnapshot(docType, docId, snapshotData);
JsonArray ops = ar.result().getArray(Key.OPS);
if (ops.size() > 0) {
log.finest("Transform Needed");
}
long snapshotV = snapshotVersion;
long opV = applyAt == null ? snapshotV + ops.size() : applyAt;
for (Object op : ops) {
JsonObject opData = (JsonObject) op;
// if (opData.containsField("seq") && opData.getString("sid") == op.getString("sid")
// && opData.getLong("seq") == op.getLong("seq")) {
// // The op has already been submitted. There's a variety of ways this can happen.
// Its
// // important we don't transform it by itself & submit again.
// callback.handle(new DefaultFutureResult<JsonObject>(new ReplyException(
// ReplyFailure.RECIPIENT_FAILURE, "Op already submitted")));
// return;
// }
// Bring both the op and the snapshot up to date. At least one of these two
// conditionals should be true.
long opVersion = opData.getLong(Key.VERSION);
if (snapshotV == opVersion) {
try {
snapshot.consume(createOperation(opData));
} catch (Exception e) {
callback.handle(new DefaultFutureResult<JsonObject>(new ReplyException(
ReplyFailure.RECIPIENT_FAILURE, e.getMessage())));
return;
}
snapshotV++;
}
if (opV == opVersion) {
transformedOps.add(opData);
opV++;
}
}
if (opV != snapshotV) {
callback.handle(new DefaultFutureResult<JsonObject>(new ReplyException(
ReplyFailure.RECIPIENT_FAILURE, "Invalid opData version")));
return;
}
CollaborativeOperation transformed = operation;
if (applyAt != null && ops.size() > 0
&& applyAt <= ops.<JsonObject>get(ops.size() - 1).getLong(Key.VERSION)) {
try {
CollaborativeOperation applied =
transformer.compose(createOperations(ops, (int) (applyAt - ops
.<JsonObject>get(0).getLong(Key.VERSION)), ops.size()));
transformed = operation.transform(applied, false);
} catch (Exception e) {
log.log(Level.WARNING, "Failed to transform operation", e);
callback.handle(new DefaultFutureResult<JsonObject>(new ReplyException(
ReplyFailure.RECIPIENT_FAILURE, e.getMessage())));
return;
}
}
// Ok, now we can try to apply the op.
try {
snapshot.consume(transformed);
} catch (Exception e) {
log.log(Level.WARNING, "Failed to consume operation", e);
callback.handle(new DefaultFutureResult<JsonObject>(new ReplyException(
ReplyFailure.RECIPIENT_FAILURE, e.getMessage())));
return;