jackrabbit-oak-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1298366 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk: ./ model/ store/
Date Thu, 08 Mar 2012 11:35:35 GMT
Author: jukka
Date: Thu Mar  8 11:35:35 2012
New Revision: 1298366

URL: http://svn.apache.org/viewvc?rev=1298366&view=rev
Log:
OAK-3: Internal tree model

Commit proposed patch to implement diffing and related operations on top of the abstract tree
model.

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeStateDiff.java
  (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/Node.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/CopyingGC.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/RevisionProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/StoredNodeAsState.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
Thu Mar  8 11:35:35 2012
@@ -20,14 +20,13 @@ import org.apache.jackrabbit.mk.api.Micr
 import org.apache.jackrabbit.mk.api.MicroKernelException;
 import org.apache.jackrabbit.mk.json.JsopBuilder;
 import org.apache.jackrabbit.mk.json.JsopTokenizer;
-import org.apache.jackrabbit.mk.model.ChildNodeEntry;
 import org.apache.jackrabbit.mk.model.Commit;
 import org.apache.jackrabbit.mk.model.CommitBuilder;
 import org.apache.jackrabbit.mk.model.Id;
 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.store.RevisionProvider;
 import org.apache.jackrabbit.mk.util.CommitGate;
 import org.apache.jackrabbit.mk.util.PathUtils;
 import org.apache.jackrabbit.mk.util.SimpleLRUCache;
@@ -207,19 +206,20 @@ public class MicroKernelImpl implements 
 
         try {
             final JsopBuilder buff = new JsopBuilder();
+            final RevisionProvider rp = rep.getRevisionStore();
             // maps (key: id of target node, value: path/to/target)
             // for tracking added/removed nodes; this allows us
             // to detect 'move' operations
             final HashMap<Id, String> addedNodes = new HashMap<Id, String>();
             final HashMap<Id, String> removedNodes = new HashMap<Id, String>();
-            StoredNode node1, node2;
+            NodeState node1, node2;
             try {
-                node1 = rep.getNode(fromRevisionId, path);
+                node1 = rep.getNodeState(fromRevisionId, path);
             } catch (NotFoundException e) {
                 node1 = null;
             }
             try {
-                node2 = rep.getNode(toRevisionId, path);
+                node2 = rep.getNodeState(toRevisionId, path);
             } catch (NotFoundException e) {
                 node2 = null;
             }
@@ -227,8 +227,7 @@ public class MicroKernelImpl implements 
             if (node1 == null) {
                 if (node2 != null) {
                     buff.tag('+').key(path).object();
-                    toJson(buff, rep.getRevisionStore().getNodeState(node2),
-                            Integer.MAX_VALUE, 0, -1, false);
+                    toJson(buff, node2, Integer.MAX_VALUE, 0, -1, false);
                     return buff.endObject().newline().toString();
                 } else {
                     throw new MicroKernelException("path doesn't exist in the specified revisions:
" + path);
@@ -239,52 +238,48 @@ public class MicroKernelImpl implements 
                 return buff.newline().toString();
             }
 
-            TraversingNodeDiffHandler diffHandler = new TraversingNodeDiffHandler(rep.getRevisionStore())
{
+            TraversingNodeDiffHandler diffHandler = new TraversingNodeDiffHandler() {
                 @Override
-                public void propAdded(String propName, String value) {
+                public void propertyAdded(PropertyState after) {
                     buff.tag('+').
-                            key(PathUtils.concat(getCurrentPath(), propName)).
-                            encodedValue(value).
+                            key(PathUtils.concat(getCurrentPath(), after.getName())).
+                            encodedValue(after.getEncodedValue()).
                             newline();
                 }
 
                 @Override
-                public void propChanged(String propName, String oldValue, String newValue)
{
+                public void propertyChanged(PropertyState before, PropertyState after) {
                     buff.tag('^').
-                            key(PathUtils.concat(getCurrentPath(), propName)).
-                            encodedValue(newValue).
+                            key(PathUtils.concat(getCurrentPath(), after.getName())).
+                            encodedValue(after.getEncodedValue()).
                             newline();
                 }
 
                 @Override
-                public void propDeleted(String propName, String value) {
+                public void propertyDeleted(PropertyState before) {
                     // 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(getCurrentPath(), propName)).
+                            key(PathUtils.concat(getCurrentPath(), before.getName())).
                             value(null).
                             newline();
                 }
 
                 @Override
-                public void childNodeAdded(ChildNodeEntry added) {
-                    addedNodes.put(added.getId(), PathUtils.concat(getCurrentPath(), added.getName()));
+                public void childNodeAdded(String name, NodeState after) {
+                    addedNodes.put(rp.getId(after), PathUtils.concat(getCurrentPath(), name));
                     buff.tag('+').
-                            key(PathUtils.concat(getCurrentPath(), added.getName())).object();
-                    try {
-                        toJson(buff, store.getNodeState(store.getNode(added.getId())), Integer.MAX_VALUE,
0, -1, false);
-                    } catch (Exception e) {
-                        buff.value("ERROR: failed to retrieve node " + added.getId());
-                    }
+                            key(PathUtils.concat(getCurrentPath(), name)).object();
+                    toJson(buff, after, Integer.MAX_VALUE, 0, -1, false);
                     buff.endObject().newline();
                 }
 
                 @Override
-                public void childNodeDeleted(ChildNodeEntry deleted) {
-                    removedNodes.put(deleted.getId(), PathUtils.concat(getCurrentPath(),
deleted.getName()));
+                public void childNodeDeleted(String name, NodeState before) {
+                    removedNodes.put(rp.getId(before), PathUtils.concat(getCurrentPath(),
name));
                     buff.tag('-');
-                    buff.value(PathUtils.concat(getCurrentPath(), deleted.getName()));
+                    buff.value(PathUtils.concat(getCurrentPath(), name));
                     buff.newline();
                 }
             };
@@ -303,58 +298,54 @@ public class MicroKernelImpl implements 
 
                 // TODO refactor code, avoid duplication
 
-                diffHandler = new TraversingNodeDiffHandler(rep.getRevisionStore()) {
+                diffHandler = new TraversingNodeDiffHandler() {
                     @Override
-                    public void propAdded(String propName, String value) {
+                    public void propertyAdded(PropertyState after) {
                         buff.tag('+').
-                                key(PathUtils.concat(getCurrentPath(), propName)).
-                                encodedValue(value).
+                                key(PathUtils.concat(getCurrentPath(), after.getName())).
+                                encodedValue(after.getEncodedValue()).
                                 newline();
                     }
 
                     @Override
-                    public void propChanged(String propName, String oldValue, String newValue)
{
+                    public void propertyChanged(PropertyState before, PropertyState after)
{
                         buff.tag('^').
-                                key(PathUtils.concat(getCurrentPath(), propName)).
-                                encodedValue(newValue).
+                                key(PathUtils.concat(getCurrentPath(), after.getName())).
+                                encodedValue(after.getEncodedValue()).
                                 newline();
                     }
 
                     @Override
-                    public void propDeleted(String propName, String value) {
+                    public void propertyDeleted(PropertyState before) {
                         // 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(getCurrentPath(), propName)).
+                                key(PathUtils.concat(getCurrentPath(), before.getName())).
                                 value(null).
                                 newline();
                     }
 
                     @Override
-                    public void childNodeAdded(ChildNodeEntry added) {
-                        if (addedNodes.containsKey(added.getId())) {
+                    public void childNodeAdded(String name, NodeState after) {
+                        if (addedNodes.containsKey(rp.getId(after))) {
                             // moved node, will be processed separately
                             return;
                         }
                         buff.tag('+').
-                                key(PathUtils.concat(getCurrentPath(), added.getName())).object();
-                        try {
-                            toJson(buff, store.getNodeState(store.getNode(added.getId())),
Integer.MAX_VALUE, 0, -1, false);
-                        } catch (Exception e) {
-                            buff.value("ERROR: failed to retrieve node " + added.getId());
-                        }
+                                key(PathUtils.concat(getCurrentPath(), name)).object();
+                        toJson(buff, after, Integer.MAX_VALUE, 0, -1, false);
                         buff.endObject().newline();
                     }
 
                     @Override
-                    public void childNodeDeleted(ChildNodeEntry deleted) {
-                        if (addedNodes.containsKey(deleted.getId())) {
+                    public void childNodeDeleted(String name, NodeState before) {
+                        if (addedNodes.containsKey(rp.getId(before))) {
                             // moved node, will be processed separately
                             return;
                         }
                         buff.tag('-');
-                        buff.value(PathUtils.concat(getCurrentPath(), deleted.getName()));
+                        buff.value(PathUtils.concat(getCurrentPath(), name));
                         buff.newline();
                     }
 
@@ -596,7 +587,7 @@ public class MicroKernelImpl implements 
 
     //-------------------------------------------------------< implementation >
 
-    void toJson(JsopBuilder builder, NodeState node, int depth, int offset, int count, boolean
inclVirtualProps) throws Exception {
+    void toJson(JsopBuilder builder, NodeState node, int depth, int offset, int count, boolean
inclVirtualProps) {
         for (PropertyState property : node.getProperties()) {
             builder.key(property.getName()).encodedValue(property.getEncodedValue());
         }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
Thu Mar  8 11:35:35 2012
@@ -131,81 +131,6 @@ 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);
-                }
-            }
-        }
-
-        // compare child node entries
-
-        if (other instanceof AbstractNode) {
-            ChildNodeEntries otherEntries = ((AbstractNode) other).childEntries;
-            for (Iterator<ChildNodeEntry> it = childEntries.getAdded(otherEntries);
it.hasNext(); ) {
-                handler.childNodeAdded(it.next());
-            }
-            for (Iterator<ChildNodeEntry> it = childEntries.getRemoved(otherEntries);
it.hasNext(); ) {
-                handler.childNodeDeleted(it.next());
-            }
-            for (Iterator<ChildNodeEntry> it = childEntries.getModified(otherEntries);
it.hasNext(); ) {
-                ChildNodeEntry old = it.next();
-                ChildNodeEntry modified = otherEntries.get(old.getName());
-                handler.childNodeChanged(old, modified.getId());
-            }
-            return;
-        }
-
-        Map<String, ChildNodeEntry> oldEntries = new HashMap<String, ChildNodeEntry>(getChildNodeCount());
-        for (Iterator<ChildNodeEntry> it = getChildNodeEntries(0, -1); it.hasNext();
) {
-            ChildNodeEntry cne = it.next();
-            oldEntries.put(cne.getName(), cne);
-        }
-        Map<String, ChildNodeEntry> newEntries = new HashMap<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(oldEntries.get(name));
-            }
-            set.clear();
-            set.addAll(newEntries.keySet());
-            set.removeAll(oldEntries.keySet());
-            for (String name : set) {
-                handler.childNodeAdded(newEntries.get(name));
-            }
-            for (ChildNodeEntry cneOld : oldEntries.values()) {
-                ChildNodeEntry cneNew = newEntries.get(cneOld.getName());
-                if (cneNew != null && !cneNew.getId().equals(cneOld.getId())) {
-                    handler.childNodeChanged(cneOld, cneNew.getId());
-                }
-            }
-        }
-    }
-
     public void serialize(Binding binding) throws Exception {
         final Iterator<Map.Entry<String, String>> iter = properties.entrySet().iterator();
         binding.writeMap(":props", properties.size(),
@@ -227,4 +152,4 @@ public abstract class AbstractNode imple
         binding.write(":inlined", childEntries.inlined() ? 1 : 0);
         childEntries.serialize(binding);
     }
-}
\ No newline at end of file
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java
Thu Mar  8 11:35:35 2012
@@ -336,8 +336,10 @@ public class CommitBuilder {
     }
 
     void mergeNode(StoredNode baseNode, StoredNode ourNode, StoredNode theirNode, String
path) throws Exception {
-        NodeDelta theirChanges = new NodeDelta(baseNode, theirNode);
-        NodeDelta ourChanges = new NodeDelta(baseNode, ourNode);
+        NodeDelta theirChanges = new NodeDelta(
+                store, store.getNodeState(baseNode), store.getNodeState(theirNode));
+        NodeDelta ourChanges = new NodeDelta(
+                store, store.getNodeState(baseNode), store.getNodeState(ourNode));
 
         // merge non-conflicting changes
         MutableNode mergedNode = new MutableNode(theirNode, store);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/Node.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/Node.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/Node.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/Node.java Thu
Mar  8 11:35:35 2012
@@ -39,7 +39,5 @@ public interface Node {
     Iterator<ChildNode> getChildNodes(int offset, int count) throws Exception;
     Node getNode(String relPath) throws NotFoundException, Exception;
 
-    void diff(Node other, NodeDiffHandler handler);
-    
     void serialize(Binding binding) throws Exception;
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDelta.java
Thu Mar  8 11:35:35 2012
@@ -21,10 +21,14 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.jackrabbit.mk.store.RevisionProvider;
+import org.apache.jackrabbit.oak.model.NodeState;
+import org.apache.jackrabbit.oak.model.PropertyState;
+
 /**
  *
  */
-public class NodeDelta implements NodeDiffHandler {
+public class NodeDelta {
 
     public static enum ConflictType {
         /**
@@ -47,8 +51,9 @@ public class NodeDelta implements NodeDi
         REMOVED_DIRTY_NODE_CONFLICT
     }
 
-    final StoredNode node1;
-    final StoredNode node2;
+    private final RevisionProvider provider;
+
+    private final NodeState node1;
 
     Map<String, String> addedProperties = new HashMap<String, String>();
     Map<String, String> removedProperties = new HashMap<String, String>();
@@ -58,11 +63,11 @@ public class NodeDelta implements NodeDi
     Map<String, Id> removedChildNodes = new HashMap<String, Id>();
     Map<String, Id> changedChildNodes = new HashMap<String, Id>();
 
-    public NodeDelta(StoredNode node1, StoredNode node2) throws Exception {
+    public NodeDelta(
+            RevisionProvider provider, NodeState node1, NodeState node2) {
+        this.provider = provider;
         this.node1 = node1;
-        this.node2 = node2;
-
-        node1.diff(node2, this);
+        new DiffHandler().compare(node1, node2);
     }
 
     public Map<String, String> getAddedProperties() {
@@ -95,7 +100,7 @@ public class NodeDelta implements NodeDi
 
     public List<Conflict> listConflicts(NodeDelta other) {
         // assume that both delta's were built using the *same* base node revision
-        if (!node1.getId().equals(other.node1.getId())) {
+        if (!node1.equals(other.node1)) {
             throw new IllegalArgumentException("other and this NodeDelta object are expected
to share common node1 instance");
         }
 
@@ -168,33 +173,42 @@ public class NodeDelta implements NodeDi
         return conflicts;
     }
 
-    //------------------------------------------------------< NodeDiffHandler >
+    //--------------------------------------------------------< inner classes >
 
-    public void propAdded(String propName, String value) {
-        addedProperties.put(propName, value);
-    }
+    private class DiffHandler extends NodeStateDiff {
 
-    public void propChanged(String propName, String oldValue, String newValue) {
-        changedProperties.put(propName, newValue);
-    }
+        @Override
+        public void propertyAdded(PropertyState after) {
+            addedProperties.put(after.getName(), after.getEncodedValue());
+        }
 
-    public void propDeleted(String propName, String value) {
-        removedProperties.put(propName, value);
-    }
+        @Override
+        public void propertyChanged(PropertyState before, PropertyState after) {
+            changedProperties.put(after.getName(), after.getEncodedValue());
+        }
 
-    public void childNodeAdded(ChildNodeEntry added) {
-        addedChildNodes.put(added.getName(), added.getId());
-    }
+        @Override
+        public void propertyDeleted(PropertyState before) {
+            removedProperties.put(before.getName(), before.getEncodedValue());
+        }
 
-    public void childNodeDeleted(ChildNodeEntry deleted) {
-        removedChildNodes.put(deleted.getName(), deleted.getId());
-    }
+        @Override
+        public void childNodeAdded(String name, NodeState after) {
+            addedChildNodes.put(name, provider.getId(after));
+        }
 
-    public void childNodeChanged(ChildNodeEntry changed, Id newId) {
-        changedChildNodes.put(changed.getName(), newId);
-    }
+        @Override
+        public void childNodeChanged(
+                String name, NodeState before, NodeState after) {
+            changedChildNodes.put(name, provider.getId(after));
+        }
 
-    //--------------------------------------------------------< inner classes >
+        @Override
+        public void childNodeDeleted(String name, NodeState before) {
+            removedChildNodes.put(name, provider.getId(before));
+        }
+
+    }
 
     public static class Conflict {
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeDiffHandler.java
Thu Mar  8 11:35:35 2012
@@ -1,35 +0,0 @@
-/*
- * 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;
-
-/**
- *
- */
-public interface NodeDiffHandler {
-
-    void propAdded(String propName, String value);
-
-    void propChanged(String propName, String oldValue, String newValue);
-
-    void propDeleted(String propName, String value);
-
-    void childNodeAdded(ChildNodeEntry added);
-
-    void childNodeDeleted(ChildNodeEntry deleted);
-
-    void childNodeChanged(ChildNodeEntry changed, Id newId);
-}

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeStateDiff.java?rev=1298366&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeStateDiff.java
(added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeStateDiff.java
Thu Mar  8 11:35:35 2012
@@ -0,0 +1,167 @@
+/*
+ * 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 java.util.HashSet;
+import java.util.Set;
+
+import org.apache.jackrabbit.oak.model.ChildNodeEntry;
+import org.apache.jackrabbit.oak.model.NodeState;
+import org.apache.jackrabbit.oak.model.PropertyState;
+
+/**
+ * Utility base class for comparing two {@link NodeState} instances. The
+ * {@link #compare(NodeState, NodeState)} method will go through all
+ * properties and child nodes of the two states, calling the relevant
+ * added, changed or deleted methods where appropriate. Differences in
+ * the ordering of properties or child nodes do not affect the comparison.
+ */
+public class NodeStateDiff {
+
+    /**
+     * Called by {@link #compare(NodeState, NodeState)} for all added
+     * properties. The default implementation does nothing.
+     *
+     * @param after property state after the change
+     */
+    public void propertyAdded(PropertyState after) {
+    }
+
+    /**
+     * Called by {@link #compare(NodeState, NodeState)} for all changed
+     * properties. The names of the given two property states are guaranteed
+     * to be the same. The default implementation does nothing.
+     *
+     * @param before property state before the change
+     * @param after property state after the change
+     */
+    public void propertyChanged(PropertyState before, PropertyState after) {
+    }
+
+    /**
+     * Called by {@link #compare(NodeState, NodeState)} for all deleted
+     * properties. The default implementation does nothing.
+     *
+     * @param before property state before the change
+     */
+    public void propertyDeleted(PropertyState before) {
+    }
+
+    /**
+     * Called by {@link #compare(NodeState, NodeState)} for all added
+     * child nodes. The default implementation does nothing.
+     *
+     * @param name name of the added child node
+     * @param after child node state after the change
+     */
+    public void childNodeAdded(String name, NodeState after) {
+    }
+
+    /**
+     * Called by {@link #compare(NodeState, NodeState)} for all changed
+     * child nodes. The default implementation does nothing.
+     *
+     * @param name name of the changed child node
+     * @param before child node state before the change
+     * @param after child node state after the change
+     */
+    public void childNodeChanged(String name, NodeState before, NodeState after) {
+    }
+
+    /**
+     * Called by {@link #compare(NodeState, NodeState)} for all deleted
+     * child nodes. The default implementation does nothing.
+     *
+     * @param name name of the deleted child node
+     * @param before child node state before the change
+     */
+    public void childNodeDeleted(String name, NodeState before) {
+    }
+
+    /**
+     * Compares the given two node states. Any found differences are
+     * reported by calling the relevant added, changed or deleted methods.
+     *
+     * @param before node state before changes
+     * @param after node state after changes
+     */
+    public void compare(NodeState before, NodeState after) {
+        compareProperties(before, after);
+        compareChildNodes(before, after);
+    }
+
+    /**
+     * Compares the properties of the given two node states.
+     *
+     * @param before node state before changes
+     * @param after node state after changes
+     */
+    private void compareProperties(NodeState before, NodeState after) {
+        Set<String> beforeProperties = new HashSet<String>();
+
+        for (PropertyState beforeProperty : before.getProperties()) {
+            String name = beforeProperty.getName();
+            PropertyState afterProperty = after.getProperty(name);
+            if (afterProperty == null) {
+                propertyDeleted(beforeProperty);
+            } else {
+                beforeProperties.add(name);
+                if (!beforeProperty.equals(afterProperty)) {
+                    propertyChanged(beforeProperty, afterProperty);
+                }
+            }
+        }
+
+        for (PropertyState afterProperty : after.getProperties()) {
+            if (!beforeProperties.contains(afterProperty.getName())) {
+                propertyAdded(afterProperty);
+            }
+        }
+    }
+
+    /**
+     * Compares the child nodes of the given two node states.
+     *
+     * @param before node state before changes
+     * @param after node state after changes
+     */
+    private void compareChildNodes(NodeState before, NodeState after) {
+        Set<String> beforeChildNodes = new HashSet<String>();
+
+        for (ChildNodeEntry beforeCNE : before.getChildNodeEntries(0, -1)) {
+            String name = beforeCNE.getName();
+            NodeState beforeChild = beforeCNE.getNode();
+            NodeState afterChild = after.getChildNode(name);
+            if (afterChild == null) {
+                childNodeDeleted(name, beforeChild);
+            } else {
+                beforeChildNodes.add(name);
+                if (!beforeChild.equals(afterChild)) {
+                    childNodeChanged(name, beforeChild, afterChild);
+                }
+            }
+        }
+
+        for (ChildNodeEntry afterChild : after.getChildNodeEntries(0, -1)) {
+            String name = afterChild.getName();
+            if (!beforeChildNodes.contains(name)) {
+                childNodeAdded(name, afterChild.getNode());
+            }
+        }
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/NodeStateDiff.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/model/TraversingNodeDiffHandler.java
Thu Mar  8 11:35:35 2012
@@ -16,68 +16,38 @@
  */
 package org.apache.jackrabbit.mk.model;
 
-import org.apache.jackrabbit.mk.store.RevisionProvider;
 import org.apache.jackrabbit.mk.util.PathUtils;
+import org.apache.jackrabbit.oak.model.NodeState;
 
 import java.util.Stack;
 
 /**
  *
  */
-public abstract class TraversingNodeDiffHandler implements NodeDiffHandler {
+public abstract class TraversingNodeDiffHandler extends NodeStateDiff {
 
-    protected final RevisionProvider store;
-    protected Stack paths = new Stack();
-    
-    public TraversingNodeDiffHandler(RevisionProvider store) {
-        this.store = store;
-    }
+    protected Stack<String> paths = new Stack<String>();
 
-    public void start(Node node1, Node node2) throws Exception {
-        start(node1, node2, "/");
+    public void start(NodeState before, NodeState after) {
+        start(before, after, "/");
     }
 
-    public void start(Node node1, Node node2, String path) throws Exception {
+    public void start(NodeState before, NodeState after, String path) {
         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) {
+        compare(before, after);
     }
 
-    public void propDeleted(String propName, String value) {
-    }
-
-    public void childNodeAdded(ChildNodeEntry added) {
-    }
-
-    public void childNodeDeleted(ChildNodeEntry deleted) {
+    protected String getCurrentPath() {
+        return paths.peek();
     }
 
-    public void childNodeChanged(ChildNodeEntry changed, Id newId) {
-        paths.push(PathUtils.concat(getCurrentPath(), changed.getName()));
-        try {
-            store.getNode(changed.getId()).diff(store.getNode(newId), this);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
+    @Override
+    public void childNodeChanged(
+            String name, NodeState before, NodeState after) {
+        paths.push(PathUtils.concat(getCurrentPath(), name));
+        compare(before, after);
         paths.pop();
     }
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/CopyingGC.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/CopyingGC.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/CopyingGC.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/CopyingGC.java
Thu Mar  8 11:35:35 2012
@@ -175,6 +175,10 @@ public class CopyingGC implements Revisi
         return new StoredNodeAsState(node, this);
     }
 
+    public Id getId(NodeState node) {
+        return ((StoredNodeAsState) node).getId();
+    }
+
     public StoredNode getNode(Id id) throws NotFoundException, Exception {
         if (running) {
             try {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
Thu Mar  8 11:35:35 2012
@@ -247,6 +247,10 @@ public class DefaultRevisionStore implem
         return new StoredNodeAsState(node, this);
     }
 
+    public Id getId(NodeState node) {
+        return ((StoredNodeAsState) node).getId();
+    }
+
     public StoredNode getNode(Id id) throws NotFoundException, Exception {
         verifyInitialized();
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/RevisionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/RevisionProvider.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/RevisionProvider.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/RevisionProvider.java
Thu Mar  8 11:35:35 2012
@@ -36,6 +36,14 @@ public interface RevisionProvider {
      */
     NodeState getNodeState(StoredNode node);
 
+    /**
+     * Adapts the given {@link NodeState} to the corresponding identifier.
+     *
+     * @param node node state
+     * @return node identifier
+     */
+    Id getId(NodeState node);
+
     StoredNode getNode(Id id) throws NotFoundException, Exception;
     StoredCommit getCommit(String id) throws NotFoundException, Exception;
     ChildNodeEntriesMap getCNEMap(Id id) throws NotFoundException, Exception;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/StoredNodeAsState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/StoredNodeAsState.java?rev=1298366&r1=1298365&r2=1298366&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/StoredNodeAsState.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/store/StoredNodeAsState.java
Thu Mar  8 11:35:35 2012
@@ -20,6 +20,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map;
 
+import org.apache.jackrabbit.mk.model.Id;
 import org.apache.jackrabbit.mk.model.StoredNode;
 import org.apache.jackrabbit.oak.model.AbstractChildNodeEntry;
 import org.apache.jackrabbit.oak.model.AbstractNodeState;
@@ -39,6 +40,10 @@ class StoredNodeAsState extends Abstract
         this.provider = provider;
     }
 
+    Id getId() {
+        return node.getId();
+    }
+
     private static class SimplePropertyState extends AbstractPropertyState {
 
         private final String name;



Mime
View raw message