}
Id revId = revisionId == null ? getHeadRevisionId() : Id.fromString(revisionId);
try {
JsopTokenizer t = new JsopTokenizer(jsonDiff);
CommitBuilder cb = rep.getCommitBuilder(revId, message);
while (true) {
int r = t.read();
if (r == JsopReader.END) {
break;
}
int pos; // used for error reporting
switch (r) {
case '+': {
pos = t.getLastPos();
String subPath = t.readString();
t.read(':');
if (t.matches('{')) {
String nodePath = PathUtils.concat(path, subPath);
if (!PathUtils.isAbsolute(nodePath)) {
throw new Exception("absolute path expected: " + nodePath + ", pos: " + pos);
}
String parentPath = PathUtils.getParentPath(nodePath);
String nodeName = PathUtils.getName(nodePath);
cb.addNode(parentPath, nodeName, parseNode(t));
} else {
String value;
if (t.matches(JsopReader.NULL)) {
value = null;
} else {
value = t.readRawValue().trim();
}
String targetPath = PathUtils.concat(path, subPath);
if (!PathUtils.isAbsolute(targetPath)) {
throw new Exception("absolute path expected: " + targetPath + ", pos: " + pos);
}
String parentPath = PathUtils.getParentPath(targetPath);
String propName = PathUtils.getName(targetPath);
cb.setProperty(parentPath, propName, value);
}
break;
}
case '-': {
pos = t.getLastPos();
String subPath = t.readString();
String targetPath = PathUtils.concat(path, subPath);
if (!PathUtils.isAbsolute(targetPath)) {
throw new Exception("absolute path expected: " + targetPath + ", pos: " + pos);
}
cb.removeNode(targetPath);
break;
}
case '^': {
pos = t.getLastPos();
String subPath = t.readString();
t.read(':');
String value;
if (t.matches(JsopReader.NULL)) {
value = null;
} else {
value = t.readRawValue().trim();
}
String targetPath = PathUtils.concat(path, subPath);
if (!PathUtils.isAbsolute(targetPath)) {
throw new Exception("absolute path expected: " + targetPath + ", pos: " + pos);
}
String parentPath = PathUtils.getParentPath(targetPath);
String propName = PathUtils.getName(targetPath);
cb.setProperty(parentPath, propName, value);
break;
}
case '>': {
pos = t.getLastPos();
String subPath = t.readString();
String srcPath = PathUtils.concat(path, subPath);
if (!PathUtils.isAbsolute(srcPath)) {
throw new Exception("absolute path expected: " + srcPath + ", pos: " + pos);
}
t.read(':');
pos = t.getLastPos();
String targetPath = t.readString();
if (!PathUtils.isAbsolute(targetPath)) {
targetPath = PathUtils.concat(path, targetPath);
if (!PathUtils.isAbsolute(targetPath)) {
throw new Exception("absolute path expected: " + targetPath + ", pos: " + pos);
}
}
cb.moveNode(srcPath, targetPath);
break;
}
case '*': {
pos = t.getLastPos();
String subPath = t.readString();
String srcPath = PathUtils.concat(path, subPath);
if (!PathUtils.isAbsolute(srcPath)) {
throw new Exception("absolute path expected: " + srcPath + ", pos: " + pos);
}
t.read(':');
pos = t.getLastPos();
String targetPath = t.readString();
if (!PathUtils.isAbsolute(targetPath)) {
targetPath = PathUtils.concat(path, targetPath);
if (!PathUtils.isAbsolute(targetPath)) {
throw new Exception("absolute path expected: " + targetPath + ", pos: " + pos);
}
}
cb.copyNode(srcPath, targetPath);
break;
}
default:
throw new AssertionError("token type: " + t.getTokenType());
}
}
Id newHead = cb.doCommit();
if (!newHead.equals(revId)) {
// non-empty commit