You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2011/12/29 23:04:20 UTC
svn commit: r1225668 - in
/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk: ./
model/
Author: stefan
Date: Thu Dec 29 22:04:19 2011
New Revision: 1225668
URL: http://svn.apache.org/viewvc?rev=1225668&view=rev
Log:
flat hierarchy support (WIP)
Added:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java
Removed:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeUtils.java
Modified:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java?rev=1225668&r1=1225667&r2=1225668&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java Thu Dec 29 22:04:19 2011
@@ -24,10 +24,9 @@ import org.apache.jackrabbit.mk.model.Ch
import org.apache.jackrabbit.mk.model.Commit;
import org.apache.jackrabbit.mk.model.CommitBuilder;
import org.apache.jackrabbit.mk.model.Node;
-import org.apache.jackrabbit.mk.model.NodeDiffHandler;
-import org.apache.jackrabbit.mk.model.NodeUtils;
import org.apache.jackrabbit.mk.model.StoredCommit;
import org.apache.jackrabbit.mk.model.StoredNode;
+import org.apache.jackrabbit.mk.model.TraversingNodeDiffHandler;
import org.apache.jackrabbit.mk.store.NotFoundException;
import org.apache.jackrabbit.mk.util.CommitGate;
import org.apache.jackrabbit.mk.util.PathUtils;
@@ -226,35 +225,39 @@ public class MicroKernelImpl implements
return buff.newline().toString();
}
- NodeUtils.diff(path, node1, node2, true, rep.getRevisionStore(), new NodeDiffHandler() {
- public void propAdded(String nodePath, String propName, String value) {
+ TraversingNodeDiffHandler diffHandler = new TraversingNodeDiffHandler(rep.getRevisionStore()) {
+ @Override
+ public void propAdded(String propName, String value) {
buff.tag('+').
- key(PathUtils.concat(nodePath, propName)).
+ key(PathUtils.concat(getCurrentPath(), propName)).
encodedValue(value).
newline();
}
- public void propChanged(String nodePath, String propName, String oldValue, String newValue) {
+ @Override
+ public void propChanged(String propName, String oldValue, String newValue) {
buff.tag('^').
- key(PathUtils.concat(nodePath, propName)).
+ key(PathUtils.concat(getCurrentPath(), propName)).
encodedValue(newValue).
newline();
}
- public void propDeleted(String nodePath, String propName, String value) {
+ @Override
+ public void propDeleted(String propName, String value) {
// since property and node deletions can't be distinguished
// using the "- <path>" notation we're representing
// property deletions as "^ <path>:null"
buff.tag('^').
- key(PathUtils.concat(nodePath, propName)).
+ key(PathUtils.concat(getCurrentPath(), propName)).
value(null).
newline();
}
- public void childNodeAdded(String nodePath, String childName, String id) {
- addedNodes.put(id, PathUtils.concat(nodePath, childName));
+ @Override
+ public void childNodeAdded(String childName, String id) {
+ addedNodes.put(id, PathUtils.concat(getCurrentPath(), childName));
buff.tag('+').
- key(PathUtils.concat(nodePath, childName)).object();
+ key(PathUtils.concat(getCurrentPath(), childName)).object();
try {
toJson(buff, rep.getRevisionStore().getNode(id), Integer.MAX_VALUE, 0, -1, false);
} catch (Exception e) {
@@ -263,17 +266,15 @@ public class MicroKernelImpl implements
buff.endObject().newline();
}
- public void childNodeDeleted(String nodePath, String childName, String id) {
- removedNodes.put(id, PathUtils.concat(nodePath, childName));
+ @Override
+ public void childNodeDeleted(String childName, String id) {
+ removedNodes.put(id, PathUtils.concat(getCurrentPath(), childName));
buff.tag('-');
- buff.value(PathUtils.concat(nodePath, childName));
+ buff.value(PathUtils.concat(getCurrentPath(), childName));
buff.newline();
}
-
- public void childNodeChanged(String nodePath, String childName, String oldId, String newId) {
- // we're not interested
- }
- });
+ };
+ diffHandler.start(node1, node2, path);
// check if this commit includes 'move' operations
// by building intersection of added and removed nodes
@@ -287,38 +288,43 @@ public class MicroKernelImpl implements
buff.reset();
// TODO refactor code, avoid duplication
- NodeUtils.diff(path, node1, node2, true, rep.getRevisionStore(), new NodeDiffHandler() {
- public void propAdded(String nodePath, String propName, String value) {
+
+ diffHandler = new TraversingNodeDiffHandler(rep.getRevisionStore()) {
+ @Override
+ public void propAdded(String propName, String value) {
buff.tag('+').
- key(PathUtils.concat(nodePath, propName)).
+ key(PathUtils.concat(getCurrentPath(), propName)).
encodedValue(value).
newline();
}
- public void propChanged(String nodePath, String propName, String oldValue, String newValue) {
+ @Override
+ public void propChanged(String propName, String oldValue, String newValue) {
buff.tag('^').
- key(PathUtils.concat(nodePath, propName)).
+ key(PathUtils.concat(getCurrentPath(), propName)).
encodedValue(newValue).
newline();
}
- public void propDeleted(String nodePath, String propName, String value) {
+ @Override
+ public void propDeleted(String propName, String value) {
// since property and node deletions can't be distinguished
// using the "- <path>" notation we're representing
// property deletions as "^ <path>:null"
buff.tag('^').
- key(PathUtils.concat(nodePath, propName)).
+ key(PathUtils.concat(getCurrentPath(), propName)).
value(null).
newline();
}
- public void childNodeAdded(String nodePath, String childName, String id) {
+ @Override
+ public void childNodeAdded(String childName, String id) {
if (addedNodes.containsKey(id)) {
// moved node, will be processed separately
return;
}
buff.tag('+').
- key(PathUtils.concat(nodePath, childName)).object();
+ key(PathUtils.concat(getCurrentPath(), childName)).object();
try {
toJson(buff, rep.getRevisionStore().getNode(id), Integer.MAX_VALUE, 0, -1, false);
} catch (Exception e) {
@@ -327,20 +333,20 @@ public class MicroKernelImpl implements
buff.endObject().newline();
}
- public void childNodeDeleted(String nodePath, String childName, String id) {
+ @Override
+ public void childNodeDeleted(String childName, String id) {
if (addedNodes.containsKey(id)) {
// moved node, will be processed separately
return;
}
buff.tag('-');
- buff.value(PathUtils.concat(nodePath, childName));
+ buff.value(PathUtils.concat(getCurrentPath(), childName));
buff.newline();
}
- public void childNodeChanged(String nodePath, String childName, String oldId, String newId) {
- // we're not interested
- }
- });
+ };
+ diffHandler.start(node1, node2, path);
+
// finally process moved nodes
for (Map.Entry<String, String> entry : addedNodes.entrySet()) {
buff.tag('>').
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java?rev=1225668&r1=1225667&r2=1225668&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java Thu Dec 29 22:04:19 2011
@@ -21,10 +21,12 @@ import org.apache.jackrabbit.mk.store.No
import org.apache.jackrabbit.mk.util.PathUtils;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
/**
*
@@ -151,6 +153,75 @@ public abstract class AbstractNode imple
return node;
}
+ public void diff(Node other, NodeDiffHandler handler) {
+ // compare properties
+ Map<String, String> oldProps = getProperties();
+ Map<String, String> newProps = other.getProperties();
+ if (!oldProps.equals(newProps)) {
+ Set<String> set = new HashSet<String>();
+ set.addAll(oldProps.keySet());
+ set.removeAll(newProps.keySet());
+ for (String name : set) {
+ handler.propDeleted(name, oldProps.get(name));
+ }
+ set.clear();
+ set.addAll(newProps.keySet());
+ set.removeAll(oldProps.keySet());
+ for (String name : set) {
+ handler.propAdded(name, newProps.get(name));
+ }
+ for (Map.Entry<String, String> entry : oldProps.entrySet()) {
+ String val = newProps.get(entry.getKey());
+ if (val != null && !entry.getValue().equals(val)) {
+ handler.propChanged(entry.getKey(), entry.getValue(), val);
+ }
+ }
+ }
+
+ // todo determine copy/move and child-node reorder operations
+
+ // compare child node entries
+
+ // todo efficiently handle large child node lists
+
+ Map<String, ChildNodeEntry> oldEntries, newEntries;
+ if (other instanceof AbstractNode) {
+ oldEntries = childEntries;
+ newEntries = ((AbstractNode) other).childEntries;
+ } else {
+ oldEntries = new LinkedHashMap<String, ChildNodeEntry>(getChildNodeCount());
+ for (Iterator<ChildNodeEntry> it = getChildNodeEntries(0, -1); it.hasNext(); ) {
+ ChildNodeEntry cne = it.next();
+ oldEntries.put(cne.getName(), cne);
+ }
+ newEntries = new LinkedHashMap<String, ChildNodeEntry>(other.getChildNodeCount());
+ for (Iterator<ChildNodeEntry> it = other.getChildNodeEntries(0, -1); it.hasNext(); ) {
+ ChildNodeEntry cne = it.next();
+ newEntries.put(cne.getName(), cne);
+ }
+ }
+ if (!oldEntries.equals(newEntries)) {
+ Set<String> set = new HashSet<String>();
+ set.addAll(oldEntries.keySet());
+ set.removeAll(newEntries.keySet());
+ for (String name : set) {
+ handler.childNodeDeleted(name, oldEntries.get(name).getId());
+ }
+ set.clear();
+ set.addAll(newEntries.keySet());
+ set.removeAll(oldEntries.keySet());
+ for (String name : set) {
+ handler.childNodeAdded(name, newEntries.get(name).getId());
+ }
+ for (ChildNodeEntry cneOld : oldEntries.values()) {
+ ChildNodeEntry cneNew = newEntries.get(cneOld.getName());
+ if (cneNew != null && !cneNew.getId().equals(cneOld.getId())) {
+ handler.childNodeChanged(cneOld.getName(), cneOld.getId(), cneNew.getId());
+ }
+ }
+ }
+ }
+
//--------------------------------------------------------< inner classes >
static class EmptyIterator<T> implements Iterator<T> {
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java?rev=1225668&r1=1225667&r2=1225668&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java Thu Dec 29 22:04:19 2011
@@ -45,4 +45,6 @@ public interface Node {
Iterator<ChildNode> getChildNodes(int offset, int count, RevisionProvider provider) throws Exception;
Node getNode(String relPath, RevisionProvider provider) throws NotFoundException, Exception;
+
+ void diff(Node other, NodeDiffHandler handler);
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java?rev=1225668&r1=1225667&r2=1225668&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java Thu Dec 29 22:04:19 2011
@@ -62,7 +62,7 @@ public class NodeDelta implements NodeDi
this.node1 = node1;
this.node2 = node2;
- NodeUtils.diff("/", node1, node2, this);
+ node1.diff(node2, this);
}
public Map<String, String> getAddedProperties() {
@@ -170,27 +170,27 @@ public class NodeDelta implements NodeDi
//------------------------------------------------------< NodeDiffHandler >
- public void propAdded(String nodePath, String propName, String value) {
+ public void propAdded(String propName, String value) {
addedProperties.put(propName, value);
}
- public void propChanged(String nodePath, String propName, String oldValue, String newValue) {
+ public void propChanged(String propName, String oldValue, String newValue) {
changedProperties.put(propName, newValue);
}
- public void propDeleted(String nodePath, String propName, String value) {
+ public void propDeleted(String propName, String value) {
removedProperties.put(propName, value);
}
- public void childNodeAdded(String nodePath, String childName, String id) {
+ public void childNodeAdded(String childName, String id) {
addedChildNodes.put(childName, id);
}
- public void childNodeDeleted(String nodePath, String childName, String id) {
+ public void childNodeDeleted(String childName, String id) {
removedChildNodes.put(childName, id);
}
- public void childNodeChanged(String nodePath, String childName,
+ public void childNodeChanged(String childName,
String oldId, String newId) {
changedChildNodes.put(childName, newId);
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java?rev=1225668&r1=1225667&r2=1225668&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java Thu Dec 29 22:04:19 2011
@@ -21,15 +21,15 @@ package org.apache.jackrabbit.mk.model;
*/
public interface NodeDiffHandler {
- void propAdded(String nodePath, String propName, String value);
+ void propAdded(String propName, String value);
- void propChanged(String nodePath, String propName, String oldValue, String newValue);
+ void propChanged(String propName, String oldValue, String newValue);
- void propDeleted(String nodePath, String propName, String value);
+ void propDeleted(String propName, String value);
- void childNodeAdded(String nodePath, String childName, String id);
+ void childNodeAdded(String childName, String id);
- void childNodeDeleted(String nodePath, String childName, String id);
+ void childNodeDeleted(String childName, String id);
- void childNodeChanged(String nodePath, String childName, String oldId, String newId);
+ void childNodeChanged(String childName, String oldId, String newId);
}
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java?rev=1225668&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java Thu Dec 29 22:04:19 2011
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.mk.model;
+
+import org.apache.jackrabbit.mk.store.RevisionProvider;
+import org.apache.jackrabbit.mk.util.PathUtils;
+
+import java.util.Stack;
+
+/**
+ *
+ */
+public abstract class TraversingNodeDiffHandler implements NodeDiffHandler {
+
+ protected final RevisionProvider store;
+ protected Stack paths = new Stack();
+
+ public TraversingNodeDiffHandler(RevisionProvider store) {
+ this.store = store;
+ }
+
+ public void start(Node node1, Node node2) throws Exception {
+ start(node1, node2, "/");
+ }
+
+ public void start(Node node1, Node node2, String path) throws Exception {
+ paths.clear();
+ paths.push(path);
+ try {
+ node1.diff(node2, this);
+ } catch (RuntimeException e) {
+ Throwable root = e.getCause();
+ if (root != null && root instanceof Exception) {
+ throw (Exception) root;
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ protected String getCurrentPath() {
+ return (String) paths.peek();
+ }
+
+ public void propAdded(String propName, String value) {
+ }
+
+ public void propChanged(String propName, String oldValue, String newValue) {
+ }
+
+ public void propDeleted(String propName, String value) {
+ }
+
+ public void childNodeAdded(String childName, String id) {
+ }
+
+ public void childNodeDeleted(String childName, String id) {
+ }
+
+ public void childNodeChanged(String childName, String oldId, String newId) {
+ paths.push(PathUtils.concat(getCurrentPath(), childName));
+ try {
+ store.getNode(oldId).diff(store.getNode(newId), this);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ paths.pop();
+ }
+}