You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2013/04/30 10:19:08 UTC

svn commit: r1477505 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/ oak-cor...

Author: jukka
Date: Tue Apr 30 08:19:07 2013
New Revision: 1477505

URL: http://svn.apache.org/r1477505
Log:
OAK-799: Fail-fast for content diffs

Add boolean return value to comparison methods

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/MergingNodeStateDiff.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/BaseDiffCollector.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MutableNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MergeDiff.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/JcrAllCommitHook.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/EditorDiff.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateDiff.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
    jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java Tue Apr 30 08:19:07 2013
@@ -84,37 +84,43 @@ class JsopDiff implements NodeStateDiff 
     //-----------------------------------------------------< NodeStateDiff >--
 
     @Override
-    public void propertyAdded(PropertyState after) {
+    public boolean propertyAdded(PropertyState after) {
         jsop.tag('^').key(buildPath(after.getName()));
         toJson(after, jsop);
+        return true;
     }
 
     @Override
-    public void propertyChanged(PropertyState before, PropertyState after) {
+    public boolean propertyChanged(PropertyState before, PropertyState after) {
         jsop.tag('^').key(buildPath(after.getName()));
         toJson(after, jsop);
+        return true;
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) {
+    public boolean propertyDeleted(PropertyState before) {
         jsop.tag('^').key(buildPath(before.getName())).value(null);
+        return true;
     }
 
     @Override
-    public void childNodeAdded(String name, NodeState after) {
+    public boolean childNodeAdded(String name, NodeState after) {
         jsop.tag('+').key(buildPath(name));
         toJson(after, jsop);
+        return true;
     }
 
     @Override
-    public void childNodeDeleted(String name, NodeState before) {
+    public boolean childNodeDeleted(String name, NodeState before) {
         jsop.tag('-').value(buildPath(name));
+        return true;
     }
 
     @Override
-    public void childNodeChanged(String name, NodeState before, NodeState after) {
+    public boolean childNodeChanged(String name, NodeState before, NodeState after) {
         String path = buildPath(name);
         after.compareAgainstBaseState(before, createChildDiff(jsop, path));
+        return true;
     }
 
     //------------------------------------------------------------< Object >--

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java Tue Apr 30 08:19:07 2013
@@ -331,36 +331,35 @@ public final class KernelNodeState exten
      * @see <a href="https://issues.apache.org/jira/browse/OAK-175">OAK-175</a>
      */
     @Override
-    public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+    public boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
         if (this == base) {
-            return; // no differences
-        } else if (base == EMPTY_NODE) {
-            EmptyNodeState.compareAgainstEmptyState(this, diff); // special case
-            return;
+            return true; // no differences
+        } else if (base == EMPTY_NODE || !base.exists()) { // special case
+            return EmptyNodeState.compareAgainstEmptyState(this, diff);
         } else if (base instanceof KernelNodeState) {
             KernelNodeState kbase = (KernelNodeState) base;
             if (kernel.equals(kbase.kernel)) {
                 if (revision.equals(kbase.revision) && path.equals(kbase.path)) {
-                    return; // no differences
+                    return true; // no differences
                 } else {
                     init();
                     kbase.init();
                     if (hash != null && hash.equals(kbase.hash)) {
-                        return; // no differences
+                        return true; // no differences
                     } else if (id != null && id.equals(kbase.id)) {
-                        return; // no differences
+                        return true; // no differences
                     } else if (path.equals(kbase.path)
                             && childNodeCount > MAX_CHILD_NODE_NAMES) {
                         // use MK.diff() when there are 'many' child nodes
                         String jsonDiff = kernel.diff(kbase.getRevision(), revision, path, 0);
                         processJsonDiff(jsonDiff, kbase, diff);
-                        return;
+                        return true;
                     }
                 }
             }
         }
         // fall back to the generic node state diff algorithm
-        super.compareAgainstBaseState(base, diff);
+        return super.compareAgainstBaseState(base, diff);
     }
 
     //------------------------------------------------------------< Object >--

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/MergingNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/MergingNodeStateDiff.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/MergingNodeStateDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/MergingNodeStateDiff.java Tue Apr 30 08:19:07 2013
@@ -75,7 +75,7 @@ public final class MergingNodeStateDiff 
     //------------------------------------------------------< NodeStateDiff >---
 
     @Override
-    public void childNodeAdded(String name, NodeState after) {
+    public boolean childNodeAdded(String name, NodeState after) {
         if (CONFLICT.equals(name)) {
             for (ChildNodeEntry conflict : after.getChildNodeEntries()) {
                 resolveConflict(conflict.getName(), conflict.getNodeState());
@@ -83,11 +83,13 @@ public final class MergingNodeStateDiff 
 
             target.removeChildNode(CONFLICT);
         }
+        return true;
     }
 
     @Override
-    public void childNodeChanged(String name, NodeState before, NodeState after) {
+    public boolean childNodeChanged(String name, NodeState before, NodeState after) {
         merge(before, after, target.child(name), conflictHandler);
+        return true;
     }
 
     //------------------------------------------------------------< private >---

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/BaseDiffCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/BaseDiffCollector.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/BaseDiffCollector.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/BaseDiffCollector.java Tue Apr 30 08:19:07 2013
@@ -88,68 +88,48 @@ public abstract class BaseDiffCollector 
         private final Filter filter;
         private final Set<String> results;
 
-        private final DiffCollectorNodeStateDiff parent;
         private final String path;
-        private boolean done;
 
         DiffCollectorNodeStateDiff(BaseDiffCollector collector, Filter filter) {
-            this(collector, filter, null, "", new HashSet<String>());
+            this(collector, filter, "", new HashSet<String>());
         }
 
-        private DiffCollectorNodeStateDiff(BaseDiffCollector collector,
-                Filter filter, DiffCollectorNodeStateDiff parent, String path,
+        private DiffCollectorNodeStateDiff(
+                BaseDiffCollector collector, Filter filter, String path,
                 Set<String> results) {
             this.collector = collector;
             this.filter = filter;
-            this.parent = parent;
             this.path = path;
             this.results = results;
         }
 
-        private boolean isDone() {
-            if (parent != null) {
-                return parent.isDone();
-            }
-            return done;
-        }
-
-        private void setDone() {
-            if (parent != null) {
-                parent.setDone();
-                return;
-            }
-            done = true;
-        }
-
         @Override
-        public void childNodeAdded(String name, NodeState after) {
-            childNodeChanged(name, EMPTY_NODE, after);
+        public boolean childNodeAdded(String name, NodeState after) {
+            return childNodeChanged(name, EMPTY_NODE, after);
         }
 
         @Override
-        public void childNodeChanged(String name, NodeState before,
+        public boolean childNodeChanged(String name, NodeState before,
                 NodeState after) {
-            if (NodeStateUtils.isHidden(name) || isDone()) {
-                return;
+            if (NodeStateUtils.isHidden(name)) {
+                return true;
             }
-            testNodeState(after, name);
-            after.compareAgainstBaseState(before,
-                    new DiffCollectorNodeStateDiff(collector, filter, this,
-                            concat(path, name), results));
+            return testNodeState(after, name)
+                    && after.compareAgainstBaseState(
+                            before,
+                            new DiffCollectorNodeStateDiff(
+                                    collector, filter,
+                                    concat(path, name), results));
         }
 
-        private void testNodeState(NodeState nodeState, String currentPath) {
-            if (isDone()) {
-                return;
-            }
-            boolean match = collector.match(nodeState, filter);
-            if (match) {
+        private boolean testNodeState(NodeState nodeState, String currentPath) {
+            if (collector.match(nodeState, filter)) {
                 results.add(concat(path, currentPath));
                 if (collector.isUnique()) {
-                    setDone();
-                    return;
+                    return false;
                 }
             }
+            return true;
         }
 
         Set<String> getResults() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java Tue Apr 30 08:19:07 2013
@@ -118,27 +118,38 @@ public final class EmptyNodeState implem
     }
 
     @Override
-    public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+    public boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
         if (base != EMPTY_NODE && base.exists()) {
             for (PropertyState before : base.getProperties()) {
-                diff.propertyDeleted(before);
+                if (!diff.propertyDeleted(before)) {
+                    return false;
+                }
             }
             for (ChildNodeEntry before : base.getChildNodeEntries()) {
-                diff.childNodeDeleted(before.getName(), before.getNodeState());
+                if (!diff.childNodeDeleted(
+                        before.getName(), before.getNodeState())) {
+                    return false;
+                }
             }
         }
+        return true;
     }
 
-    public static void compareAgainstEmptyState(
+    public static boolean compareAgainstEmptyState(
             NodeState state, NodeStateDiff diff) {
         if (state != EMPTY_NODE && state.exists()) {
             for (PropertyState after : state.getProperties()) {
-                diff.propertyAdded(after);
+                if (!diff.propertyAdded(after)) {
+                    return false;
+                }
             }
             for (ChildNodeEntry after : state.getChildNodeEntries()) {
-                diff.childNodeAdded(after.getName(), after.getNodeState());
+                if (!diff.childNodeAdded(after.getName(), after.getNodeState())) {
+                    return false;
+                }
             }
         }
+        return true;
     }
 
     public static boolean isEmptyState(NodeState state) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java Tue Apr 30 08:19:07 2013
@@ -121,10 +121,9 @@ class MemoryNodeState extends AbstractNo
      * a generic diff against the given state.
      */
     @Override
-    public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+    public boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
         if (base == EMPTY_NODE || !base.exists()) {
-            EmptyNodeState.compareAgainstEmptyState(this, diff);
-            return;
+            return EmptyNodeState.compareAgainstEmptyState(this, diff);
         }
 
         Map<String, PropertyState> newProperties =
@@ -132,13 +131,20 @@ class MemoryNodeState extends AbstractNo
         for (PropertyState before : base.getProperties()) {
             PropertyState after = newProperties.remove(before.getName());
             if (after == null) {
-                diff.propertyDeleted(before);
+                if (!diff.propertyDeleted(before)) {
+                    return false;
+                }
             } else if (!after.equals(before)) {
-                diff.propertyChanged(before, after);
+                if (!diff.propertyChanged(before, after)) {
+                    return false;
+                }
             }
         }
+
         for (PropertyState after : newProperties.values()) {
-            diff.propertyAdded(after);
+            if (!diff.propertyAdded(after)) {
+                return false;
+            }
         }
 
         Map<String, NodeState> newNodes =
@@ -148,14 +154,23 @@ class MemoryNodeState extends AbstractNo
             NodeState before = entry.getNodeState();
             NodeState after = newNodes.remove(name);
             if (after == null) {
-                diff.childNodeDeleted(name, before);
+                if (!diff.childNodeDeleted(name, before)) {
+                    return false;
+                }
             } else if (!after.equals(before)) {
-                diff.childNodeChanged(name, before, after);
+                if (!diff.childNodeChanged(name, before, after)) {
+                    return false;
+                }
             }
         }
+
         for (Map.Entry<String, NodeState> entry : newNodes.entrySet()) {
-            diff.childNodeAdded(entry.getKey(), entry.getValue());
+            if (!diff.childNodeAdded(entry.getKey(), entry.getValue())) {
+                return false;
+            }
         }
+
+        return true;
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java Tue Apr 30 08:19:07 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.oak.plugins.memory;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Predicates.notNull;
 import static com.google.common.collect.Collections2.filter;
@@ -28,8 +27,6 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry.iterable;
 
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -269,47 +266,43 @@ public class ModifiedNodeState extends A
      * and child nodes to those in the given base state.
      */
     @Override
-    public void compareAgainstBaseState(
+    public boolean compareAgainstBaseState(
             NodeState base, final NodeStateDiff diff) {
-        this.base.compareAgainstBaseState(base, new NodeStateDiff() {
+        if (!this.base.compareAgainstBaseState(base, new NodeStateDiff() {
             @Override
-            public void propertyAdded(PropertyState after) {
-                if (!properties.containsKey(after.getName())) {
-                    diff.propertyAdded(after);
-                }
+            public boolean propertyAdded(PropertyState after) {
+                return properties.containsKey(after.getName())
+                        || diff.propertyAdded(after);
             }
             @Override
-            public void propertyChanged(
+            public boolean propertyChanged(
                     PropertyState before, PropertyState after) {
-                if (!properties.containsKey(before.getName())) {
-                    diff.propertyChanged(before, after);
-                }
+                return properties.containsKey(before.getName())
+                        || diff.propertyChanged(before, after);
             }
             @Override
-            public void propertyDeleted(PropertyState before) {
-                if (!properties.containsKey(before.getName())) {
-                    diff.propertyDeleted(before);
-                }
+            public boolean propertyDeleted(PropertyState before) {
+                return properties.containsKey(before.getName())
+                        || diff.propertyDeleted(before);
             }
             @Override
-            public void childNodeAdded(String name, NodeState after) {
-                if (!nodes.containsKey(name)) {
-                    diff.childNodeAdded(name, after);
-                }
+            public boolean childNodeAdded(String name, NodeState after) {
+                return nodes.containsKey(name)
+                        || diff.childNodeAdded(name, after);
             }
             @Override
-            public void childNodeChanged(String name, NodeState before, NodeState after) {
-                if (!nodes.containsKey(name)) {
-                    diff.childNodeChanged(name, before, after);
-                }
+            public boolean childNodeChanged(String name, NodeState before, NodeState after) {
+                return nodes.containsKey(name)
+                        || diff.childNodeChanged(name, before, after);
             }
             @Override
-            public void childNodeDeleted(String name, NodeState before) {
-                if (!nodes.containsKey(name)) {
-                    diff.childNodeDeleted(name, before);
-                }
+            public boolean childNodeDeleted(String name, NodeState before) {
+                return nodes.containsKey(name)
+                        || diff.childNodeDeleted(name, before);
             }
-        });
+        })) {
+            return false;
+        }
 
         for (Map.Entry<String, ? extends PropertyState> entry : properties.entrySet()) {
             PropertyState before = base.getProperty(entry.getKey());
@@ -317,11 +310,17 @@ public class ModifiedNodeState extends A
             if (before == null && after == null) {
                 // do nothing
             } else if (after == null) {
-                diff.propertyDeleted(before);
+                if (!diff.propertyDeleted(before)) {
+                    return false; 
+                }
             } else if (before == null) {
-                diff.propertyAdded(after);
+                if (!diff.propertyAdded(after)) {
+                    return false;
+                }
             } else if (!before.equals(after)) {
-                diff.propertyChanged(before, after);
+                if (!diff.propertyChanged(before, after)) {
+                    return false;
+                }
             }
         }
 
@@ -331,14 +330,22 @@ public class ModifiedNodeState extends A
             NodeState after = entry.getValue();
             if (after == null) {
                 if (before.exists()) {
-                    diff.childNodeDeleted(name, before);
+                    if (!diff.childNodeDeleted(name, before)) {
+                        return false;
+                    }
                 }
             } else if (!before.exists()) {
-                diff.childNodeAdded(name, after);
+                if (!diff.childNodeAdded(name, after)) {
+                    return false;
+                }
             } else if (!before.equals(after)) {
-                diff.childNodeChanged(name, before, after);
+                if (!diff.childNodeChanged(name, before, after)) {
+                    return false;
+                }
             }
         }
+
+        return true;
     }
 
     public void compareAgainstBaseState(NodeStateDiff diff) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MutableNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MutableNodeState.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MutableNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MutableNodeState.java Tue Apr 30 08:19:07 2013
@@ -77,30 +77,36 @@ class MutableNodeState extends AbstractN
             this.base = modified.getBaseState();
             modified.compareAgainstBaseState(new NodeStateDiff() {
                 @Override
-                public void propertyAdded(PropertyState after) {
+                public boolean propertyAdded(PropertyState after) {
                     properties.put(after.getName(), after);
+                    return true;
                 }
                 @Override
-                public void propertyChanged(
+                public boolean propertyChanged(
                         PropertyState before, PropertyState after) {
                     properties.put(after.getName(), after);
+                    return true;
                 }
                 @Override
-                public void propertyDeleted(PropertyState before) {
+                public boolean propertyDeleted(PropertyState before) {
                     properties.put(before.getName(), null);
+                    return true;
                 }
                 @Override
-                public void childNodeAdded(String name, NodeState after) {
+                public boolean childNodeAdded(String name, NodeState after) {
                     nodes.put(name, new MutableNodeState(after));
+                    return true;
                 }
                 @Override
-                public void childNodeChanged(
+                public boolean childNodeChanged(
                         String name, NodeState before, NodeState after) {
                     nodes.put(name, new MutableNodeState(after));
+                    return true;
                 }
                 @Override
-                public void childNodeDeleted(String name, NodeState before) {
+                public boolean childNodeDeleted(String name, NodeState before) {
                     nodes.put(name, null);
+                    return true;
                 }
             });
         } else {
@@ -153,29 +159,33 @@ class MutableNodeState extends AbstractN
 
             modified.compareAgainstBaseState(new NodeStateDiff() {
                 @Override
-                public void propertyAdded(PropertyState after) {
+                public boolean propertyAdded(PropertyState after) {
                     properties.put(after.getName(), after);
+                    return true;
                 }
                 @Override
-                public void propertyChanged(
+                public boolean propertyChanged(
                         PropertyState before, PropertyState after) {
                     properties.put(after.getName(), after);
+                    return true;
                 }
                 @Override
-                public void propertyDeleted(PropertyState before) {
+                public boolean propertyDeleted(PropertyState before) {
                     properties.put(before.getName(), null);
+                    return true;
                 }
                 @Override
-                public void childNodeAdded(String name, NodeState after) {
+                public boolean childNodeAdded(String name, NodeState after) {
                     MutableNodeState cstate = nodes.get(name);
                     if (cstate != null) {
                         cstate.reset(after);
                     } else {
                         nodes.put(name, new MutableNodeState(after));
                     }
+                    return true;
                 }
                 @Override
-                public void childNodeChanged(
+                public boolean childNodeChanged(
                         String name, NodeState before, NodeState after) {
                     MutableNodeState cstate = nodes.get(name);
                     if (cstate != null) {
@@ -183,10 +193,12 @@ class MutableNodeState extends AbstractN
                     } else {
                         nodes.put(name, new MutableNodeState(after));
                     }
+                    return true;
                 }
                 @Override
-                public void childNodeDeleted(String name, NodeState before) {
+                public boolean childNodeDeleted(String name, NodeState before) {
                     nodes.put(name, null);
+                    return true;
                 }
             });
         } else {
@@ -419,7 +431,7 @@ class MutableNodeState extends AbstractN
     }
 
     @Override
-    public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+    public boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
         throw new UnsupportedOperationException();
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java Tue Apr 30 08:19:07 2013
@@ -168,76 +168,72 @@ class ChangeProcessor implements Runnabl
         }
 
         @Override
-        public void propertyAdded(PropertyState after) {
-            if (NodeStateUtils.isHidden(after.getName())) {
-                return;
-            }
-            if (!stopping && filterRef.get().include(Event.PROPERTY_ADDED, jcrPath(), associatedParentNode)) {
+        public boolean propertyAdded(PropertyState after) {
+            if (!NodeStateUtils.isHidden(after.getName())
+                    && filterRef.get().include(Event.PROPERTY_ADDED, jcrPath(), associatedParentNode)) {
                 Event event = generatePropertyEvent(Event.PROPERTY_ADDED, path, after);
                 events.add(Iterators.singletonIterator(event));
             }
+            return !stopping;
         }
 
         @Override
-        public void propertyChanged(PropertyState before, PropertyState after) {
-            if (NodeStateUtils.isHidden(before.getName())) {
-                return;
-            }
-            if (!stopping && filterRef.get().include(Event.PROPERTY_CHANGED, jcrPath(), associatedParentNode)) {
+        public boolean propertyChanged(PropertyState before, PropertyState after) {
+            if (!NodeStateUtils.isHidden(before.getName())
+                    && filterRef.get().include(Event.PROPERTY_CHANGED, jcrPath(), associatedParentNode)) {
                 Event event = generatePropertyEvent(Event.PROPERTY_CHANGED, path, after);
                 events.add(Iterators.singletonIterator(event));
             }
+            return !stopping;
         }
 
         @Override
-        public void propertyDeleted(PropertyState before) {
-            if (NodeStateUtils.isHidden(before.getName())) {
-                return;
-            }
-            if (!stopping && filterRef.get().include(Event.PROPERTY_REMOVED, jcrPath(), associatedParentNode)) {
+        public boolean propertyDeleted(PropertyState before) {
+            if (!NodeStateUtils.isHidden(before.getName())
+                    && filterRef.get().include(Event.PROPERTY_REMOVED, jcrPath(), associatedParentNode)) {
                 Event event = generatePropertyEvent(Event.PROPERTY_REMOVED, path, before);
                 events.add(Iterators.singletonIterator(event));
             }
+            return !stopping;
         }
 
         @Override
-        public void childNodeAdded(String name, NodeState after) {
-            if (NodeStateUtils.isHidden(name)) {
-                return;
-            }
-            if (!stopping && filterRef.get().includeChildren(jcrPath())) {
+        public boolean childNodeAdded(String name, NodeState after) {
+            if (!NodeStateUtils.isHidden(name)
+                    && filterRef.get().includeChildren(jcrPath())) {
                 Iterator<Event> events = generateNodeEvents(Event.NODE_ADDED, path, name, after);
                 this.events.add(events);
                 if (++childNodeCount > PURGE_LIMIT) {
                     sendEvents();
                 }
             }
+            return !stopping;
         }
 
         @Override
-        public void childNodeDeleted(String name, NodeState before) {
-            if (NodeStateUtils.isHidden(name)) {
-                return;
-            }
-            if (!stopping && filterRef.get().includeChildren(jcrPath())) {
+        public boolean childNodeDeleted(String name, NodeState before) {
+            if (!NodeStateUtils.isHidden(name)
+                    && filterRef.get().includeChildren(jcrPath())) {
                 Iterator<Event> events = generateNodeEvents(Event.NODE_REMOVED, path, name, before);
                 this.events.add(events);
             }
+            return !stopping;
         }
 
         @Override
-        public void childNodeChanged(String name, NodeState before, NodeState after) {
-            if (NodeStateUtils.isHidden(name)) {
-                return;
-            }
-            if (!stopping && filterRef.get().includeChildren(jcrPath())) {
+        public boolean childNodeChanged(String name, NodeState before, NodeState after) {
+            if (!NodeStateUtils.isHidden(name)
+                    && filterRef.get().includeChildren(jcrPath())) {
                 EventGeneratingNodeStateDiff diff = new EventGeneratingNodeStateDiff(
                         PathUtils.concat(path, name), events, after);
-                after.compareAgainstBaseState(before, diff);
+                if (!after.compareAgainstBaseState(before, diff)) {
+                    return false;
+                }
                 if (events.size() > PURGE_LIMIT) {
                     diff.sendEvents();
                 }
             }
+            return !stopping;
         }
 
         private Event generatePropertyEvent(int eventType, String parentPath, PropertyState property) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MergeDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MergeDiff.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MergeDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MergeDiff.java Tue Apr 30 08:19:07 2013
@@ -30,50 +30,56 @@ class MergeDiff implements NodeStateDiff
     }
 
     @Override
-    public void propertyAdded(PropertyState after) {
+    public boolean propertyAdded(PropertyState after) {
         if (!builder.hasProperty(after.getName())) {
             builder.setProperty(after);
         }
+        return true;
     }
 
     @Override
-    public void propertyChanged(PropertyState before, PropertyState after) {
+    public boolean propertyChanged(PropertyState before, PropertyState after) {
         PropertyState other = builder.getProperty(before.getName());
         if (other != null && other.equals(before)) {
             builder.setProperty(after);
         }
+        return true;
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) {
+    public boolean propertyDeleted(PropertyState before) {
         PropertyState other = builder.getProperty(before.getName());
         if (other != null && other.equals(before)) {
             builder.removeProperty(before.getName());
         }
+        return true;
     }
 
     @Override
-    public void childNodeAdded(String name, NodeState after) {
+    public boolean childNodeAdded(String name, NodeState after) {
         if (!builder.hasChildNode(name)) {
             builder.setChildNode(name, after);
         }
+        return true;
     }
 
     @Override
-    public void childNodeChanged(
+    public boolean childNodeChanged(
             String name, NodeState before, NodeState after) {
         if (builder.hasChildNode(name)) {
             after.compareAgainstBaseState(
                     before, new MergeDiff(builder.child(name)));
         }
+        return true;
     }
 
     @Override
-    public void childNodeDeleted(String name, NodeState before) {
+    public boolean childNodeDeleted(String name, NodeState before) {
         if (builder.hasChildNode(name)
                 && before.equals(builder.child(name).getNodeState())) {
             builder.removeChildNode(name);
         }
+        return true;
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java Tue Apr 30 08:19:07 2013
@@ -129,20 +129,19 @@ class SegmentNodeState extends AbstractN
     }
 
     @Override
-    public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+    public boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
         if (base == this) {
-             return; // no changes
-        } else if (base == EMPTY_NODE) {
-            EmptyNodeState.compareAgainstEmptyState(this, diff); // special case
+             return true; // no changes
+        } else if (base == EMPTY_NODE || !base.exists()) { // special case
+            return EmptyNodeState.compareAgainstEmptyState(this, diff);
         } else if (base instanceof SegmentNodeState) {
             SegmentNodeState that = (SegmentNodeState) base;
-            if (!recordId.equals(that.recordId)) {
-                getTemplate().compareAgainstBaseState(
+            return recordId.equals(that.recordId)
+                || getTemplate().compareAgainstBaseState(
                         store, recordId, that.getTemplate(), that.recordId,
                         diff);
-            }
         } else {
-            super.compareAgainstBaseState(base, diff); // fallback
+            return super.compareAgainstBaseState(base, diff); // fallback
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java Tue Apr 30 08:19:07 2013
@@ -661,17 +661,20 @@ public class SegmentWriter {
                 base = before.getChildNodeMap();
                 after.compareAgainstBaseState(before, new DefaultNodeStateDiff() {
                     @Override
-                    public void childNodeAdded(String name, NodeState after) {
+                    public boolean childNodeAdded(String name, NodeState after) {
                         childNodes.put(name, writeNode(after).getRecordId());
+                        return true;
                     }
                     @Override
-                    public void childNodeChanged(
+                    public boolean childNodeChanged(
                             String name, NodeState before, NodeState after) {
                         childNodes.put(name, writeNode(after).getRecordId());
+                        return true;
                     }
                     @Override
-                    public void childNodeDeleted(String name, NodeState before) {
+                    public boolean childNodeDeleted(String name, NodeState before) {
                         childNodes.put(name, null);
+                        return true;
                     }
                 });
             } else {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java Tue Apr 30 08:19:07 2013
@@ -346,7 +346,7 @@ class Template {
         }
     }
 
-    public void compareAgainstBaseState(
+    public boolean compareAgainstBaseState(
             SegmentStore store, RecordId afterId,
             Template beforeTemplate, RecordId beforeId,
             NodeStateDiff diff) {
@@ -357,8 +357,10 @@ class Template {
         checkNotNull(diff);
 
         // Compare type properties
-        compareProperties(beforeTemplate.primaryType, primaryType, diff);
-        compareProperties(beforeTemplate.mixinTypes, mixinTypes, diff);
+        if (!compareProperties(beforeTemplate.primaryType, primaryType, diff)
+                || !compareProperties(beforeTemplate.mixinTypes, mixinTypes, diff)) {
+            return false;
+        }
 
         // Compare other properties, leveraging the ordering
         int beforeIndex = 0;
@@ -383,22 +385,31 @@ class Template {
                 beforeProperty = beforeTemplate.getProperty(
                         store, beforeId, beforeIndex++);
             }
-            compareProperties(beforeProperty, afterProperty, diff);
+            if (!compareProperties(beforeProperty, afterProperty, diff)) {
+                return false;
+            }
         }
         while (afterIndex < properties.length) {
-            diff.propertyAdded(getProperty(store, afterId, afterIndex++));
+            if (!diff.propertyAdded(getProperty(store, afterId, afterIndex++))) {
+                return false;
+            }
         }
         while (beforeIndex < beforeTemplate.properties.length) {
-            diff.propertyDeleted(beforeTemplate.getProperty(
-                    store, beforeId, beforeIndex++));
+            PropertyState beforeProperty = beforeTemplate.getProperty(
+                    store, beforeId, beforeIndex++);
+            if (!diff.propertyDeleted(beforeProperty)) {
+                return false;
+            }
         }
 
         if (hasNoChildNodes()) {
             if (!beforeTemplate.hasNoChildNodes()) {
                 for (ChildNodeEntry entry :
                         beforeTemplate.getChildNodeEntries(store, beforeId)) {
-                    diff.childNodeDeleted(
-                            entry.getName(), entry.getNodeState());
+                    if (!diff.childNodeDeleted(
+                            entry.getName(), entry.getNodeState())) {
+                        return false;
+                    }
                 }
             }
         } else if (hasOneChildNode()) {
@@ -406,17 +417,23 @@ class Template {
             NodeState beforeNode = beforeTemplate.getChildNode(
                     childName, store, beforeId);
             if (!beforeNode.exists()) {
-                diff.childNodeAdded(childName, afterNode);
+                if (!diff.childNodeAdded(childName, afterNode)) {
+                    return false;
+                }
             } else if (!beforeNode.equals(afterNode)) {
-                diff.childNodeChanged(childName, beforeNode, afterNode);
+                if (!diff.childNodeChanged(childName, beforeNode, afterNode)) {
+                    return false;
+                }
             }
             if ((beforeTemplate.hasOneChildNode() && !beforeNode.exists())
                     || beforeTemplate.hasManyChildNodes()) {
                 for (ChildNodeEntry entry :
                     beforeTemplate.getChildNodeEntries(store, beforeId)) {
                     if (!childName.equals(entry.getName())) {
-                        diff.childNodeDeleted(
-                                entry.getName(), entry.getNodeState());
+                        if (!diff.childNodeDeleted(
+                                entry.getName(), entry.getNodeState())) {
+                            return false;
+                        }
                     }
                 }
             }
@@ -429,11 +446,15 @@ class Template {
                 NodeState beforeChild = beforeCNE.getNodeState();
                 NodeState afterChild = getChildNode(name, store, afterId);
                 if (!afterChild.exists()) {
-                    diff.childNodeDeleted(name, beforeChild);
+                    if (!diff.childNodeDeleted(name, beforeChild)) {
+                        return false;
+                    }
                 } else {
                     baseChildNodes.add(name);
                     if (!beforeChild.equals(afterChild)) {
-                        diff.childNodeChanged(name, beforeChild, afterChild);
+                        if (!diff.childNodeChanged(name, beforeChild, afterChild)) {
+                            return false;
+                        }
                     }
                 }
             }
@@ -441,22 +462,24 @@ class Template {
                     : getChildNodeEntries(store, afterId)) {
                 String name = afterChild.getName();
                 if (!baseChildNodes.contains(name)) {
-                    diff.childNodeAdded(name, afterChild.getNodeState());
+                    if (!diff.childNodeAdded(name, afterChild.getNodeState())) {
+                        return false;
+                    }
                 }
             }
         }
+
+        return true;
     }
 
-    private void compareProperties(
+    private boolean compareProperties(
             PropertyState before, PropertyState after, NodeStateDiff diff) {
         if (before == null) {
-            if (after != null) {
-                diff.propertyAdded(after);
-            }
+            return after == null || diff.propertyAdded(after);
         } else if (after == null) {
-            diff.propertyDeleted(before);
-        } else if (!before.equals(after)) {
-            diff.propertyChanged(before, after);
+            return diff.propertyDeleted(before);
+        } else {
+            return before.equals(after) || diff.propertyChanged(before, after);
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java Tue Apr 30 08:19:07 2013
@@ -70,7 +70,7 @@ public class VersionablePathHook impleme
         }
 
         @Override
-        public void propertyAdded(PropertyState after) {
+        public boolean propertyAdded(PropertyState after) {
             if (VersionConstants.JCR_VERSIONHISTORY.equals(after.getName())
                     && nodeAfter.isVersionable(versionManager)) {
                 NodeBuilder vhBuilder = versionManager.getOrCreateVersionHistory(nodeAfter.builder);
@@ -85,17 +85,20 @@ public class VersionablePathHook impleme
                 String versionablePath = nodeAfter.path;
                 vhBuilder.setProperty(workspaceName, versionablePath);
             }
+            return true;
         }
 
         @Override
-        public void childNodeAdded(String name, NodeState after) {
-            childNodeChanged(name, EMPTY_NODE, after);
+        public boolean childNodeAdded(String name, NodeState after) {
+            return childNodeChanged(name, EMPTY_NODE, after);
         }
 
         @Override
-        public void childNodeChanged(String name, NodeState before, NodeState after) {
+        public boolean childNodeChanged(
+                String name, NodeState before, NodeState after) {
             Node node = new Node(nodeAfter, name);
-            after.compareAgainstBaseState(before, new Diff(versionManager, node));
+            return after.compareAgainstBaseState(
+                    before, new Diff(versionManager, node));
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java Tue Apr 30 08:19:07 2013
@@ -48,9 +48,9 @@ import org.apache.jackrabbit.oak.securit
 import org.apache.jackrabbit.oak.spi.commit.PostValidationHook;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
 import org.apache.jackrabbit.oak.util.TreeUtil;
 import org.apache.jackrabbit.util.Text;
@@ -137,7 +137,7 @@ public class PermissionHook implements P
         return restrictionProvider.readRestrictions(Strings.emptyToNull(accessControlledPath), aceTree);
     }
 
-    private class Diff implements NodeStateDiff {
+    private class Diff extends DefaultNodeStateDiff {
 
         private final Node parentBefore;
         private final AfterNode parentAfter;
@@ -150,12 +150,7 @@ public class PermissionHook implements P
         }
 
         @Override
-        public void propertyAdded(PropertyState after) {
-            // nothing to do
-        }
-
-        @Override
-        public void propertyChanged(PropertyState before, PropertyState after) {
+        public boolean propertyChanged(PropertyState before, PropertyState after) {
             if (isACL(parentAfter) && TreeImpl.OAK_CHILD_ORDER.equals(before.getName())) {
                 List<String> reordered = new ChildOrderDiff(before, after).getReordered();
                 for (String name : reordered) {
@@ -167,15 +162,11 @@ public class PermissionHook implements P
                     processed.add(name);
                 }
             }
+            return true;
         }
 
         @Override
-        public void propertyDeleted(PropertyState before) {
-            // nothing to do
-        }
-
-        @Override
-        public void childNodeAdded(String name, NodeState after) {
+        public boolean childNodeAdded(String name, NodeState after) {
             if (NodeStateUtils.isHidden(name)) {
                 // ignore hidden nodes
             } else if (isACE(name, after)) {
@@ -185,10 +176,11 @@ public class PermissionHook implements P
                 AfterNode node = new AfterNode(parentAfter, name);
                 after.compareAgainstBaseState(before.getNodeState(), new Diff(before, node));
             }
+            return true;
         }
 
         @Override
-        public void childNodeChanged(String name, final NodeState before, NodeState after) {
+        public boolean childNodeChanged(String name, final NodeState before, NodeState after) {
             if (NodeStateUtils.isHidden(name)) {
                 // ignore hidden nodes
             } else if (isACE(name, before) || isACE(name, after)) {
@@ -198,10 +190,11 @@ public class PermissionHook implements P
                 AfterNode nodeAfter = new AfterNode(parentAfter, name);
                 after.compareAgainstBaseState(before, new Diff(nodeBefore, nodeAfter));
             }
+            return true;
         }
 
         @Override
-        public void childNodeDeleted(String name, NodeState before) {
+        public boolean childNodeDeleted(String name, NodeState before) {
             if (NodeStateUtils.isHidden(name)) {
                 // ignore hidden nodes
             } else if (isACE(name, before)) {
@@ -211,6 +204,7 @@ public class PermissionHook implements P
                 AfterNode after = new AfterNode(parentAfter.getPath(), name, EMPTY_NODE);
                 after.getNodeState().compareAgainstBaseState(before, new Diff(nodeBefore, after));
             }
+            return true;
         }
 
         //--------------------------------------------------------< private >---

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/JcrAllCommitHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/JcrAllCommitHook.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/JcrAllCommitHook.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/JcrAllCommitHook.java Tue Apr 30 08:19:07 2013
@@ -57,7 +57,7 @@ class JcrAllCommitHook implements PostVa
         }
 
         @Override
-        public void childNodeAdded(String name, NodeState after) {
+        public boolean childNodeAdded(String name, NodeState after) {
             if (PRIVILEGES_PATH.equals(path) && !JCR_ALL.equals(name)) {
                 // a new privilege was registered -> update the jcr:all privilege
                 NodeBuilder jcrAll = nodeBuilder.child(JCR_ALL);
@@ -82,13 +82,15 @@ class JcrAllCommitHook implements PostVa
                     jcrAll.setProperty(PrivilegeBits.getInstance(all).add(bits).asPropertyState(REP_BITS));
                 }
             }
+            return true;
         }
 
         @Override
-        public void childNodeChanged(String name, NodeState before, NodeState after) {
+        public boolean childNodeChanged(String name, NodeState before, NodeState after) {
             if (ROOT_PATH.equals(path) || Text.isDescendant(path, PRIVILEGES_PATH)) {
                 after.compareAgainstBaseState(before, new PrivilegeDiff(this, name, nodeBuilder.child(name)));
             }
+            return true;
         }
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/EditorDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/EditorDiff.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/EditorDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/EditorDiff.java Tue Apr 30 08:19:07 2013
@@ -89,72 +89,72 @@ public class EditorDiff implements NodeS
     //-------------------------------------------------< NodeStateDiff >--
 
     @Override
-    public void propertyAdded(PropertyState after) {
-        if (exception == null) {
-            try {
-                editor.propertyAdded(after);
-            } catch (CommitFailedException e) {
-                exception = e;
-            }
+    public boolean propertyAdded(PropertyState after) {
+        try {
+            editor.propertyAdded(after);
+            return true;
+        } catch (CommitFailedException e) {
+            exception = e;
+            return false;
         }
     }
 
     @Override
-    public void propertyChanged(PropertyState before, PropertyState after) {
-        if (exception == null) {
-            try {
-                editor.propertyChanged(before, after);
-            } catch (CommitFailedException e) {
-                exception = e;
-            }
+    public boolean propertyChanged(PropertyState before, PropertyState after) {
+        try {
+            editor.propertyChanged(before, after);
+            return true;
+        } catch (CommitFailedException e) {
+            exception = e;
+            return false;
         }
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) {
-        if (exception == null) {
-            try {
-                editor.propertyDeleted(before);
-            } catch (CommitFailedException e) {
-                exception = e;
-            }
+    public boolean propertyDeleted(PropertyState before) {
+        try {
+            editor.propertyDeleted(before);
+            return true;
+        } catch (CommitFailedException e) {
+            exception = e;
+            return false;
         }
     }
 
     @Override
-    public void childNodeAdded(String name, NodeState after) {
-        if (exception == null) {
-            try {
-                Editor e = editor.childNodeAdded(name, after);
-                exception = process(e, MISSING_NODE, after);
-            } catch (CommitFailedException e) {
-                exception = e;
-            }
+    public boolean childNodeAdded(String name, NodeState after) {
+        try {
+            Editor e = editor.childNodeAdded(name, after);
+            exception = process(e, MISSING_NODE, after);
+            return exception == null;
+        } catch (CommitFailedException e) {
+            exception = e;
+            return false;
         }
     }
 
     @Override
-    public void childNodeChanged(
+    public boolean childNodeChanged(
             String name, NodeState before, NodeState after) {
-        if (exception == null) {
-            try {
-                Editor e = editor.childNodeChanged(name, before, after);
-                exception = process(e, before, after);
-            } catch (CommitFailedException e) {
-                exception = e;
-            }
+        try {
+            Editor e = editor.childNodeChanged(name, before, after);
+            exception = process(e, before, after);
+            return exception == null;
+        } catch (CommitFailedException e) {
+            exception = e;
+            return false;
         }
     }
 
     @Override
-    public void childNodeDeleted(String name, NodeState before) {
-        if (exception == null) {
-            try {
-                Editor e = editor.childNodeDeleted(name, before);
-                exception = process(e, before, MISSING_NODE);
-            } catch (CommitFailedException e) {
-                exception = e;
-            }
+    public boolean childNodeDeleted(String name, NodeState before) {
+        try {
+            Editor e = editor.childNodeDeleted(name, before);
+            exception = process(e, before, MISSING_NODE);
+            return exception == null;
+        } catch (CommitFailedException e) {
+            exception = e;
+            return false;
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java Tue Apr 30 08:19:07 2013
@@ -124,28 +124,40 @@ public abstract class AbstractNodeState 
      * the entries one by one with corresponding ones (if any) in this state.
      */
     @Override
-    public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
-        comparePropertiesAgainstBaseState(base, diff);
+    public boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+        if (!comparePropertiesAgainstBaseState(base, diff)) {
+            return false;
+        }
+
         Set<String> baseChildNodes = new HashSet<String>();
         for (ChildNodeEntry beforeCNE : base.getChildNodeEntries()) {
             String name = beforeCNE.getName();
             NodeState beforeChild = beforeCNE.getNodeState();
             NodeState afterChild = getChildNode(name);
             if (!afterChild.exists()) {
-                diff.childNodeDeleted(name, beforeChild);
+                if (!diff.childNodeDeleted(name, beforeChild)) {
+                    return false;
+                }
             } else {
                 baseChildNodes.add(name);
                 if (!beforeChild.equals(afterChild)) {
-                    diff.childNodeChanged(name, beforeChild, afterChild);
+                    if (!diff.childNodeChanged(name, beforeChild, afterChild)) {
+                        return false;
+                    }
                 }
             }
         }
+
         for (ChildNodeEntry afterChild : getChildNodeEntries()) {
             String name = afterChild.getName();
             if (!baseChildNodes.contains(name)) {
-                diff.childNodeAdded(name, afterChild.getNodeState());
+                if (!diff.childNodeAdded(name, afterChild.getNodeState())) {
+                    return false;
+                }
             }
         }
+
+        return true;
     }
 
     /**
@@ -239,26 +251,35 @@ public abstract class AbstractNodeState 
      * @param base the base node state.
      * @param diff the node state diff.
      */
-    protected void comparePropertiesAgainstBaseState(NodeState base,
+    protected boolean comparePropertiesAgainstBaseState(NodeState base,
                                                      NodeStateDiff diff) {
         Set<String> baseProperties = new HashSet<String>();
         for (PropertyState beforeProperty : base.getProperties()) {
             String name = beforeProperty.getName();
             PropertyState afterProperty = getProperty(name);
             if (afterProperty == null) {
-                diff.propertyDeleted(beforeProperty);
+                if (!diff.propertyDeleted(beforeProperty)) {
+                    return false;
+                }
             } else {
                 baseProperties.add(name);
                 if (!beforeProperty.equals(afterProperty)) {
-                    diff.propertyChanged(beforeProperty, afterProperty);
+                    if (!diff.propertyChanged(beforeProperty, afterProperty)) {
+                        return false;
+                    }
                 }
             }
         }
+
         for (PropertyState afterProperty : getProperties()) {
             if (!baseProperties.contains(afterProperty.getName())) {
-                diff.propertyAdded(afterProperty);
+                if (!diff.propertyAdded(afterProperty)) {
+                    return false;
+                }
             }
         }
+
+        return true;
     }
 
     //-----------------------------------------------------------< private >--

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java Tue Apr 30 08:19:07 2013
@@ -165,17 +165,18 @@ public abstract class AbstractRebaseDiff
     protected abstract void deleteChangedNode(NodeBuilder builder, String name, NodeState before);
 
     @Override
-    public void propertyAdded(PropertyState after) {
+    public boolean propertyAdded(PropertyState after) {
         PropertyState other = builder.getProperty(after.getName());
         if (other == null) {
             builder.setProperty(after);
         } else if (!other.equals(after)) {
             addExistingProperty(builder, other, after);
         }
+        return true;
     }
 
     @Override
-    public void propertyChanged(PropertyState before, PropertyState after) {
+    public boolean propertyChanged(PropertyState before, PropertyState after) {
         PropertyState other = builder.getProperty(before.getName());
         if (other == null) {
             changeDeletedProperty(builder, after);
@@ -184,10 +185,11 @@ public abstract class AbstractRebaseDiff
         } else if (!other.equals(after)) {
             changeChangedProperty(builder, before, after);
         }
+        return true;
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) {
+    public boolean propertyDeleted(PropertyState before) {
         PropertyState other = builder.getProperty(before.getName());
         if (other == null) {
             deleteDeletedProperty(builder, before);
@@ -196,30 +198,33 @@ public abstract class AbstractRebaseDiff
         } else {
             deleteChangedProperty(builder, before);
         }
+        return true;
     }
 
     @Override
-    public void childNodeAdded(String name, NodeState after) {
+    public boolean childNodeAdded(String name, NodeState after) {
         if (builder.hasChildNode(name)) {
             NodeState other = builder.child(name).getNodeState();
             addExistingNode(builder, name, other, after);
         } else {
             builder.setChildNode(name, after);
         }
+        return true;
     }
 
     @Override
-    public void childNodeChanged(
+    public boolean childNodeChanged(
             String name, NodeState before, NodeState after) {
         if (builder.hasChildNode(name)) {
             after.compareAgainstBaseState(before, createDiff(builder, name));
         } else {
             changeDeletedNode(builder, name, after);
         }
+        return true;
     }
 
     @Override
-    public void childNodeDeleted(String name, NodeState before) {
+    public boolean childNodeDeleted(String name, NodeState before) {
         if (!builder.hasChildNode(name)) {
             deleteDeletedNode(builder, name, before);
         } else if (before.equals(builder.child(name).getNodeState())) {
@@ -227,5 +232,7 @@ public abstract class AbstractRebaseDiff
         } else {
             deleteChangedNode(builder, name, before);
         }
+        return true;
     }
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java Tue Apr 30 08:19:07 2013
@@ -27,36 +27,34 @@ import org.apache.jackrabbit.oak.api.Pro
  */
 public class DefaultNodeStateDiff implements NodeStateDiff {
 
-    public static final NodeStateDiff INSTANCE = new DefaultNodeStateDiff();
-
     @Override
-    public void propertyAdded(PropertyState after) {
-        // do nothing
+    public boolean propertyAdded(PropertyState after) {
+        return true;
     }
 
     @Override
-    public void propertyChanged(PropertyState before, PropertyState after) {
-        // do nothing
+    public boolean propertyChanged(PropertyState before, PropertyState after) {
+        return true;
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) {
-        // do nothing
+    public boolean propertyDeleted(PropertyState before) {
+        return true;
     }
 
     @Override
-    public void childNodeAdded(String name, NodeState after) {
-        // do nothing
+    public boolean childNodeAdded(String name, NodeState after) {
+        return true;
     }
 
     @Override
-    public void childNodeChanged(String name, NodeState before, NodeState after) {
-        // do nothing
+    public boolean childNodeChanged(String name, NodeState before, NodeState after) {
+        return true;
     }
 
     @Override
-    public void childNodeDeleted(String name, NodeState before) {
-        // do nothing
+    public boolean childNodeDeleted(String name, NodeState before) {
+        return true;
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java Tue Apr 30 08:19:07 2013
@@ -303,8 +303,8 @@ public interface NodeState {
      *
      * @param base base state
      * @param diff handler of node state differences
-     * @since 0ak 0.4
+     * @since 0ak 0.4, return value added in 0.7
      */
-    void compareAgainstBaseState(NodeState base, NodeStateDiff diff);
+    boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff);
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateDiff.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateDiff.java Tue Apr 30 08:19:07 2013
@@ -22,12 +22,18 @@ import org.apache.jackrabbit.oak.api.Pro
  * Handler of node state differences. The
  * {@link NodeState#compareAgainstBaseState(NodeState, NodeStateDiff)}
  * method reports detected node state differences by calling methods of
- * a handler instance that implements this interface. The compare 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, and the order in which such differences are reported
- * is unspecified.
+ * a handler instance that implements this interface.
+ * <p>
+ * The compare method goes 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, and the order in which such
+ * differences are reported is unspecified.
+ * <p>
+ * The methods in this interface all return a boolean value to signify
+ * whether the comparison should continue. If a method returns {@code false},
+ * then the comparison is immediately stopped. Otherwise it continues until
+ * all changes have been reported.
  * <p>
  * Note that the
  * {@link NodeState#compareAgainstBaseState(NodeState, NodeStateDiff)}
@@ -42,8 +48,9 @@ public interface NodeStateDiff {
      * Called for all added properties.
      *
      * @param after property state after the change
+     * @return {@code true} to continue the comparison, {@code false} to stop
      */
-    void propertyAdded(PropertyState after);
+    boolean propertyAdded(PropertyState after);
 
     /**
      * Called for all changed properties. The names of the given two
@@ -51,23 +58,26 @@ public interface NodeStateDiff {
      *
      * @param before property state before the change
      * @param after property state after the change
+     * @return {@code true} to continue the comparison, {@code false} to stop
      */
-    void propertyChanged(PropertyState before, PropertyState after);
+    boolean propertyChanged(PropertyState before, PropertyState after);
 
     /**
      * Called for all deleted properties.
      *
      * @param before property state before the change
+     * @return {@code true} to continue the comparison, {@code false} to stop
      */
-    void propertyDeleted(PropertyState before);
+    boolean propertyDeleted(PropertyState before);
 
     /**
      * Called for all added child nodes.
      *
      * @param name name of the added child node
      * @param after child node state after the change
+     * @return {@code true} to continue the comparison, {@code false} to stop
      */
-    void childNodeAdded(String name, NodeState after);
+    boolean childNodeAdded(String name, NodeState after);
 
     /**
      * Called for all changed child nodes.
@@ -75,15 +85,17 @@ public interface NodeStateDiff {
      * @param name name of the changed child node
      * @param before child node state before the change
      * @param after child node state after the change
+     * @return {@code true} to continue the comparison, {@code false} to stop
      */
-    void childNodeChanged(String name, NodeState before, NodeState after);
+    boolean childNodeChanged(String name, NodeState before, NodeState after);
 
     /**
      * Called for all deleted child nodes.
      *
      * @param name name of the deleted child node
      * @param before child node state before the change
+     * @return {@code true} to continue the comparison, {@code false} to stop
      */
-    void childNodeDeleted(String name, NodeState before);
+    boolean childNodeDeleted(String name, NodeState before);
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java Tue Apr 30 08:19:07 2013
@@ -292,25 +292,27 @@ public class KernelNodeStoreTest {
         List<String> removed = new ArrayList<String>();
 
         @Override
-        public void childNodeAdded(String name, NodeState after) {
+        public boolean childNodeAdded(String name, NodeState after) {
             added.add(name);
+            return true;
         }
 
         @Override
-        public void childNodeDeleted(String name, NodeState before) {
+        public boolean childNodeDeleted(String name, NodeState before) {
             removed.add(name);
+            return true;
         }
 
         @Override
-        public void childNodeChanged(String name,
-                                     NodeState before,
-                                     NodeState after) {
-            after.compareAgainstBaseState(before, this);
+        public boolean childNodeChanged(
+                String name, NodeState before, NodeState after) {
+            return after.compareAgainstBaseState(before, this);
         }
 
         @Override
-        public void propertyAdded(PropertyState after) {
+        public boolean propertyAdded(PropertyState after) {
             addedProperties.add(after.getName());
+            return true;
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java Tue Apr 30 08:19:07 2013
@@ -17,6 +17,10 @@
 package org.apache.jackrabbit.oak.plugins.segment;
 
 import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
 
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -49,10 +53,10 @@ public class CompareAgainstBaseStateTest
     public void testSameState() {
         NodeState node = persist(builder);
 
-        EasyMock.replay(diff);
+        replay(diff);
 
         node.compareAgainstBaseState(node, diff);
-        EasyMock.verify(diff);
+        verify(diff);
     }
 
     @Test
@@ -60,10 +64,10 @@ public class CompareAgainstBaseStateTest
         NodeState before = persist(builder);
         NodeState after = persist(builder);
 
-        EasyMock.replay(diff);
+        replay(diff);
 
         after.compareAgainstBaseState(before, diff);
-        EasyMock.verify(diff);
+        verify(diff);
     }
 
     @Test
@@ -72,11 +76,11 @@ public class CompareAgainstBaseStateTest
         builder.setProperty("test", "test");
         NodeState after = persist(builder);
 
-        diff.propertyAdded(after.getProperty("test"));
-        EasyMock.replay(diff);
+        expect(diff.propertyAdded(after.getProperty("test"))).andReturn(true);
+        replay(diff);
 
         after.compareAgainstBaseState(before, diff);
-        EasyMock.verify(diff);
+        verify(diff);
     }
 
     @Test
@@ -85,12 +89,12 @@ public class CompareAgainstBaseStateTest
         builder.setProperty("foo", "test");
         NodeState after = persist(builder);
 
-        diff.propertyChanged(
-                before.getProperty("foo"), after.getProperty("foo"));
-        EasyMock.replay(diff);
+        expect(diff.propertyChanged(
+                before.getProperty("foo"), after.getProperty("foo"))).andReturn(true);
+        replay(diff);
 
         after.compareAgainstBaseState(before, diff);
-        EasyMock.verify(diff);
+        verify(diff);
     }
 
     @Test
@@ -99,11 +103,11 @@ public class CompareAgainstBaseStateTest
         builder.removeProperty("foo");
         NodeState after = persist(builder);
 
-        diff.propertyDeleted(before.getProperty("foo"));
-        EasyMock.replay(diff);
+        expect(diff.propertyDeleted(before.getProperty("foo"))).andReturn(true);
+        replay(diff);
 
         after.compareAgainstBaseState(before, diff);
-        EasyMock.verify(diff);
+        verify(diff);
     }
 
     @Test
@@ -112,11 +116,11 @@ public class CompareAgainstBaseStateTest
         builder.child("test");
         NodeState after = persist(builder);
 
-        diff.childNodeAdded("test", after.getChildNode("test"));
-        EasyMock.replay(diff);
+        expect(diff.childNodeAdded("test", after.getChildNode("test"))).andReturn(true);
+        replay(diff);
 
         after.compareAgainstBaseState(before, diff);
-        EasyMock.verify(diff);
+        verify(diff);
     }
 
     @Test
@@ -125,12 +129,12 @@ public class CompareAgainstBaseStateTest
         builder.child("baz").setProperty("test", "test");
         NodeState after = persist(builder);
 
-        diff.childNodeChanged(
-                "baz", before.getChildNode("baz"), after.getChildNode("baz"));
-        EasyMock.replay(diff);
+        expect(diff.childNodeChanged(
+                "baz", before.getChildNode("baz"), after.getChildNode("baz"))).andReturn(true);
+        replay(diff);
 
         after.compareAgainstBaseState(before, diff);
-        EasyMock.verify(diff);
+        verify(diff);
     }
 
     @Test
@@ -139,11 +143,11 @@ public class CompareAgainstBaseStateTest
         builder.removeChildNode("baz");
         NodeState after = persist(builder);
 
-        diff.childNodeDeleted("baz", before.getChildNode("baz"));
-        EasyMock.replay(diff);
+        expect(diff.childNodeDeleted("baz", before.getChildNode("baz"))).andReturn(true);
+        replay(diff);
 
         after.compareAgainstBaseState(before, diff);
-        EasyMock.verify(diff);
+        verify(diff);
     }
 
     private NodeState persist(NodeBuilder builder) {

Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java?rev=1477505&r1=1477504&r2=1477505&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java Tue Apr 30 08:19:07 2013
@@ -116,31 +116,34 @@ class SolrNodeStateDiff implements NodeS
     }
 
     @Override
-    public void propertyAdded(PropertyState after) {
+    public boolean propertyAdded(PropertyState after) {
         // TODO implement this
+        return true;
     }
 
     @Override
-    public void propertyChanged(PropertyState before, PropertyState after) {
+    public boolean propertyChanged(PropertyState before, PropertyState after) {
         // TODO implement this
+        return true;
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) {
+    public boolean propertyDeleted(PropertyState before) {
         // TODO implement this
+        return true;
     }
 
     @Override
-    public void childNodeAdded(String name, NodeState after) {
+    public boolean childNodeAdded(String name, NodeState after) {
         if (NodeStateUtils.isHidden(name)) {
-            return;
+            return true;
         }
-        if (exception == null) {
-            try {
-                addSubtree(name, after);
-            } catch (IOException e) {
-                exception = e;
-            }
+        try {
+            addSubtree(name, after);
+            return true;
+        } catch (IOException e) {
+            exception = e;
+            return false;
         }
     }
 
@@ -149,32 +152,33 @@ class SolrNodeStateDiff implements NodeS
     }
 
     @Override
-    public void childNodeChanged(String name, NodeState before, NodeState after) {
+    public boolean childNodeChanged(
+            String name, NodeState before, NodeState after) {
         if (NodeStateUtils.isHidden(name)) {
-            return;
+            return true;
         }
-        if (exception == null) {
-            try {
-                SolrNodeStateDiff diff = new SolrNodeStateDiff(solrServer);
-                after.compareAgainstBaseState(before, diff);
-                diff.postProcess(after);
-            } catch (IOException e) {
-                exception = e;
-            }
+        try {
+            SolrNodeStateDiff diff = new SolrNodeStateDiff(solrServer);
+            after.compareAgainstBaseState(before, diff);
+            diff.postProcess(after);
+            return true;
+        } catch (IOException e) {
+            exception = e;
+            return false;
         }
     }
 
     @Override
-    public void childNodeDeleted(String name, NodeState before) {
+    public boolean childNodeDeleted(String name, NodeState before) {
         if (NodeStateUtils.isHidden(name)) {
-            return;
+            return true;
         }
-        if (exception == null) {
-            try {
-                deleteSubtree(name, before);
-            } catch (IOException e) {
-                exception = e;
-            }
+        try {
+            deleteSubtree(name, before);
+            return true;
+        } catch (IOException e) {
+            exception = e;
+            return false;
         }
     }