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 md...@apache.org on 2013/06/07 12:39:28 UTC
svn commit: r1490575 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/observation/
main/java/org/apache/jackrabbit/oak/spi/state/
test/java/org/apache/jackrabbit/oak/
Author: mduerig
Date: Fri Jun 7 10:39:27 2013
New Revision: 1490575
URL: http://svn.apache.org/r1490575
Log:
OAK-775 Implement backward compatible observation
wrap diffing of changes into ac check wrapper
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/RecursingNodeStateDiff.java (with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java (with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecureNodeStateDiff.java (with props)
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/SecureNodeStateDiffTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.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/spi/state/VisibleDiff.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java?rev=1490575&r1=1490574&r2=1490575&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java Fri Jun 7 10:39:27 2013
@@ -262,9 +262,9 @@ public class ChangeDispatcher {
* {@link NodeStateDiff} of the changes
* @param diff node state diff instance for traversing the changes.
*/
- public void diff(NodeStateDiff diff) {
- // TODO wrap diff into access check wrapper
- after.compareAgainstBaseState(before, diff);
+ public void diff(RecursingNodeStateDiff diff) {
+ NodeStateDiff secureDiff = SecureNodeStateDiff.wrap(diff);
+ after.compareAgainstBaseState(before, secureDiff);
}
@Override
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=1490575&r1=1490574&r2=1490575&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 Fri Jun 7 10:39:27 2013
@@ -26,6 +26,7 @@ import java.util.concurrent.ScheduledFut
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+import javax.annotation.Nonnull;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventListener;
@@ -40,7 +41,6 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher.Listener;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
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.spi.state.VisibleDiff;
import org.slf4j.Logger;
@@ -48,9 +48,6 @@ import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
-/**
- * TODO document
- */
class ChangeProcessor implements Runnable {
private static final Logger log = LoggerFactory.getLogger(ChangeProcessor.class);
private static final Marker DEPRECATED = MarkerFactory.getMarker("deprecated");
@@ -189,7 +186,7 @@ class ChangeProcessor implements Runnabl
//------------------------------------------------------------< private >---
- private class EventGeneratingNodeStateDiff implements NodeStateDiff {
+ private class EventGeneratingNodeStateDiff extends RecursingNodeStateDiff {
public static final int PURGE_LIMIT = 8192;
private final ChangeSet changes;
@@ -209,6 +206,7 @@ class ChangeProcessor implements Runnabl
}
public EventGeneratingNodeStateDiff(ChangeSet changes) {
+ // FIXME associatedParentNode should be the root node here
this(changes, "/", new ArrayList<Iterator<Event>>(PURGE_LIMIT), null);
}
@@ -280,17 +278,19 @@ class ChangeProcessor implements Runnabl
@Override
public boolean childNodeChanged(String name, NodeState before, NodeState after) {
+ return !stopping;
+ }
+
+ @Nonnull
+ @Override
+ public RecursingNodeStateDiff createChildDiff(String name, NodeState before, NodeState after) {
if (filterRef.get().includeChildren(jcrPath())) {
EventGeneratingNodeStateDiff diff = new EventGeneratingNodeStateDiff(
changes, PathUtils.concat(path, name), events, after);
- if (!after.compareAgainstBaseState(before, VisibleDiff.wrap(diff))) {
- return false;
- }
- if (events.size() > PURGE_LIMIT) {
- diff.sendEvents();
- }
+ return VisibleDiff.wrap(diff);
+ } else {
+ return new RecursingNodeStateDiff();
}
- return !stopping;
}
private EventImpl createEvent(int eventType, String jcrPath) {
@@ -350,6 +350,7 @@ class ChangeProcessor implements Runnabl
return Iterators.concat(nodeEvent, propertyEvents, childNodeEvents);
}
+ // FIXME this doesn't correctly track the associated parent node
private Iterator<Iterator<Event>> generateChildEvents(final int eventType, final String parentPath, NodeState node) {
return Iterators.transform(
Iterators.filter(node.getChildNodeEntries().iterator(),
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/RecursingNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/RecursingNodeStateDiff.java?rev=1490575&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/RecursingNodeStateDiff.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/RecursingNodeStateDiff.java Fri Jun 7 10:39:27 2013
@@ -0,0 +1,34 @@
+/*
+ * 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.oak.plugins.observation;
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+public class RecursingNodeStateDiff extends DefaultNodeStateDiff {
+ public static final RecursingNodeStateDiff EMPTY = new RecursingNodeStateDiff();
+
+ @Nonnull
+ public RecursingNodeStateDiff createChildDiff(String name, NodeState before, NodeState after) {
+ return this;
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/RecursingNodeStateDiff.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/RecursingNodeStateDiff.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java?rev=1490575&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java Fri Jun 7 10:39:27 2013
@@ -0,0 +1,153 @@
+/*
+ * 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.oak.plugins.observation;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
+
+public abstract class SecurableNodeStateDiff implements NodeStateDiff {
+ private final SecurableNodeStateDiff parent;
+
+ private RecursingNodeStateDiff diff;
+ private Deferred deferred = Deferred.EMPTY;
+
+ private SecurableNodeStateDiff(SecurableNodeStateDiff parent, RecursingNodeStateDiff diff) {
+ this.diff = diff;
+ this.parent = parent;
+ }
+
+ protected SecurableNodeStateDiff(SecurableNodeStateDiff parent) {
+ this(parent, RecursingNodeStateDiff.EMPTY);
+ }
+
+ protected SecurableNodeStateDiff(RecursingNodeStateDiff diff) {
+ this(null, diff);
+ }
+
+ protected abstract SecurableNodeStateDiff create(SecurableNodeStateDiff parent,
+ String name, NodeState before, NodeState after);
+
+ protected boolean canRead(PropertyState before, PropertyState after) {
+ return true;
+ }
+
+ protected boolean canRead(String name, NodeState before, NodeState after) {
+ return true;
+ }
+
+ protected NodeState secureBefore(String name, NodeState nodeState) {
+ return nodeState;
+ }
+
+ protected NodeState secureAfter(String name, NodeState nodeState) {
+ return nodeState;
+ }
+
+ @Override
+ public boolean propertyAdded(PropertyState after) {
+ if (canRead(null, after)) {
+ return applyDeferred() && diff.propertyAdded(after);
+ }
+ else {
+ return true;
+ }
+ }
+
+ @Override
+ public boolean propertyChanged(PropertyState before, PropertyState after) {
+ if (canRead(before, after)) {
+ return applyDeferred() && diff.propertyChanged(before, after);
+ }
+ else {
+ return true;
+ }
+ }
+
+ @Override
+ public boolean propertyDeleted(PropertyState before) {
+ if (canRead(before, null)) {
+ return applyDeferred() && diff.propertyDeleted(before);
+ }
+ else {
+ return true;
+ }
+ }
+
+ @Override
+ public boolean childNodeAdded(String name, NodeState after) {
+ if (canRead(name, null, after)) {
+ return applyDeferred() && diff.childNodeAdded(name, secureAfter(name, after));
+ } else {
+ return true;
+ }
+ }
+
+ @Override
+ public boolean childNodeChanged(final String name, final NodeState before, final NodeState after) {
+ final SecurableNodeStateDiff childDiff = create(this, name, before, after);
+ deferred = new Deferred() {
+ @Override
+ boolean call() {
+ if (applyDeferred() && diff.childNodeChanged(name, secureBefore(name, before), secureAfter(name, after))) {
+ childDiff.diff = diff.createChildDiff(name, secureBefore(name, before), secureAfter(name, after));
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+ return after.compareAgainstBaseState(before, childDiff);
+ }
+
+ @Override
+ public boolean childNodeDeleted(String name, NodeState before) {
+ if (canRead(name, before, null)) {
+ return applyDeferred() && diff.childNodeDeleted(name, secureBefore(name, before));
+ } else {
+ return true;
+ }
+ }
+
+ private boolean applyDeferred() {
+ return parent == null || parent.deferred.apply();
+ }
+
+ //------------------------------------------------------------< Deferred >---
+
+ private abstract static class Deferred {
+ public static final Deferred EMPTY = new Deferred() {
+ @Override
+ boolean call() {
+ return true;
+ }
+ };
+
+ private Boolean result;
+
+ boolean apply() {
+ if (result == null) {
+ result = call();
+ }
+ return result;
+ }
+ abstract boolean call();
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecurableNodeStateDiff.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecureNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecureNodeStateDiff.java?rev=1490575&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecureNodeStateDiff.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecureNodeStateDiff.java Fri Jun 7 10:39:27 2013
@@ -0,0 +1,70 @@
+/*
+ * 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.oak.plugins.observation;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
+
+public class SecureNodeStateDiff extends SecurableNodeStateDiff {
+ private SecureNodeStateDiff(RecursingNodeStateDiff diff) {
+ super(diff);
+ }
+
+ private SecureNodeStateDiff(SecurableNodeStateDiff parent) {
+ super(parent);
+ }
+
+ public static NodeStateDiff wrap(RecursingNodeStateDiff diff) {
+ return new SecureNodeStateDiff(diff);
+ }
+
+ @Override
+ protected SecurableNodeStateDiff create(SecurableNodeStateDiff parent,
+ String name, NodeState before, NodeState after) {
+
+ return new SecureNodeStateDiff(parent);
+ }
+
+ @Override
+ protected boolean canRead(PropertyState before, PropertyState after) {
+ // TODO implement canRead
+ return true;
+ }
+
+ @Override
+ protected boolean canRead(String name, NodeState before, NodeState after) {
+ // TODO implement canRead
+ return true;
+ }
+
+ @Override
+ protected NodeState secureBefore(String name, NodeState nodeState) {
+ // TODO implement secureBefore
+ return nodeState;
+ }
+
+ @Override
+ protected NodeState secureAfter(String name, NodeState nodeState) {
+ // TODO implement secureAfter
+ return nodeState;
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecureNodeStateDiff.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/SecureNodeStateDiff.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/VisibleDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/VisibleDiff.java?rev=1490575&r1=1490574&r2=1490575&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/VisibleDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/VisibleDiff.java Fri Jun 7 10:39:27 2013
@@ -25,6 +25,7 @@ import static org.apache.jackrabbit.oak.
import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.observation.RecursingNodeStateDiff;
/**
* {@code NodeStateDiff} wrapper that passes only changes to non-hidden nodes and properties
@@ -32,16 +33,16 @@ import org.apache.jackrabbit.oak.api.Pro
*
* @since Oak 0.9
*/
-public class VisibleDiff implements NodeStateDiff {
+public class VisibleDiff extends RecursingNodeStateDiff {
private final NodeStateDiff diff;
@Nonnull
- public static NodeStateDiff wrap(@Nonnull NodeStateDiff diff) {
+ public static RecursingNodeStateDiff wrap(@Nonnull NodeStateDiff diff) {
return new VisibleDiff(checkNotNull(diff));
}
- public VisibleDiff(NodeStateDiff diff) {
- this.diff = checkNotNull(diff);
+ private VisibleDiff(NodeStateDiff diff) {
+ this.diff = diff;
}
@Override
@@ -97,4 +98,18 @@ public class VisibleDiff implements Node
return true;
}
}
+
+ @Nonnull
+ @Override
+ public RecursingNodeStateDiff createChildDiff(String name, NodeState before, NodeState after) {
+ if (diff instanceof RecursingNodeStateDiff) {
+ if (isHidden(name)) {
+ return RecursingNodeStateDiff.EMPTY;
+ } else {
+ return ((RecursingNodeStateDiff) diff).createChildDiff(name, before, after);
+ }
+ } else {
+ return super.createChildDiff(name, before, after);
+ }
+ }
}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/SecureNodeStateDiffTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/SecureNodeStateDiffTest.java?rev=1490575&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/SecureNodeStateDiffTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/SecureNodeStateDiffTest.java Fri Jun 7 10:39:27 2013
@@ -0,0 +1,204 @@
+/*
+ * 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.oak;
+
+import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.observation.RecursingNodeStateDiff;
+import org.apache.jackrabbit.oak.plugins.observation.SecurableNodeStateDiff;
+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.junit.Before;
+import org.junit.Test;
+
+public class SecureNodeStateDiffTest {
+ private NodeState base;
+
+ @Before
+ public void setUp() {
+ NodeBuilder builder = EMPTY_NODE.builder();
+ builder.setProperty("a", 1L);
+ builder.setProperty("b", 2L);
+ builder.setProperty("c", 3L);
+ builder.child("x");
+ builder.child("y");
+ builder.child("z");
+ builder.child("NA1").child("x1");
+ builder.child("NA2").child("x2").child("y3");
+ builder.child("NA3").child("x3").child("NA3a").child("y3");
+ base = builder.getNodeState();
+ }
+
+ @Test
+ public void testRemoveNode() {
+ NodeBuilder builder = base.builder();
+ builder.child("x").remove();
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("-x");
+ }
+
+ @Test
+ public void testAddNode() {
+ NodeBuilder builder = base.builder();
+ builder.child("v");
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("+v");
+ }
+
+ @Test
+ public void testRemoveProperty() {
+ NodeBuilder builder = base.builder();
+ builder.removeProperty("a");
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("-a");
+ }
+
+ @Test
+ public void testAddProperty() {
+ NodeBuilder builder = base.builder();
+ builder.setProperty("d", "d");
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("+d");
+ }
+
+ @Test
+ public void testChangeProperty() {
+ NodeBuilder builder = base.builder();
+ builder.setProperty("c", 42);
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("^c");
+ }
+
+ @Test
+ public void testChangeNode() {
+ NodeBuilder builder = base.builder();
+ builder.child("NA1").setProperty("p", "p");
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("^NA1+p");
+ }
+
+ @Test
+ public void testAddInaccessibleChild() {
+ NodeBuilder builder = base.builder();
+ builder.child("NA3").child("x3").child("NA3a").child("y3").child("NA3a");
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("");
+ }
+
+ @Test
+ public void testChangeInaccessibleChild() {
+ NodeBuilder builder = base.builder();
+ builder.child("NA3").child("x3").child("NA3a").child("y3").remove();
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("^NA3^x3^NA3a-y3");
+ }
+
+ @Test
+ public void testRemoveInaccessibleChild() {
+ NodeBuilder builder = base.builder();
+ builder.child("NA3").child("x3").child("NA3a").remove();
+ new AssertingNodeStateDiff(base, builder.getNodeState()).expect("");
+ }
+
+ private static class SecureNodeStateDiff extends SecurableNodeStateDiff {
+ protected SecureNodeStateDiff(SecurableNodeStateDiff parent) {
+ super(parent);
+ }
+
+ public static NodeStateDiff wrap(RecursingNodeStateDiff diff) {
+ return new SecureNodeStateDiff(diff);
+ }
+
+ private SecureNodeStateDiff(RecursingNodeStateDiff diff) {
+ super(diff);
+ }
+
+ @Override
+ protected SecurableNodeStateDiff create(SecurableNodeStateDiff parent,
+ String name, NodeState before, NodeState after) {
+ return new SecureNodeStateDiff(parent);
+ }
+
+ @Override
+ protected boolean canRead(PropertyState before, PropertyState after) {
+ return canRead(before) && canRead(after);
+ }
+
+ private static boolean canRead(PropertyState property) {
+ return property == null || canRead(property.getName());
+ }
+
+ @Override
+ protected boolean canRead(String name, NodeState before, NodeState after) {
+ return canRead(name);
+ }
+
+ private static boolean canRead(String name) {
+ return name == null || !name.startsWith("NA");
+ }
+ }
+
+ private static class AssertingNodeStateDiff extends RecursingNodeStateDiff {
+ private final StringBuilder actual = new StringBuilder();
+ private final NodeState before;
+ private final NodeState after;
+
+ public AssertingNodeStateDiff(NodeState before, NodeState after) {
+ this.before = before;
+ this.after = after;
+ }
+
+ public void expect(String expected) {
+ after.compareAgainstBaseState(before, SecureNodeStateDiff.wrap(this));
+ assertEquals(expected, actual.toString());
+ }
+
+ @Override
+ public boolean propertyAdded(PropertyState after) {
+ actual.append('+').append(after.getName());
+ return true;
+ }
+
+ @Override
+ public boolean propertyChanged(PropertyState before, PropertyState after) {
+ actual.append('^').append(after.getName());
+ return true;
+ }
+
+ @Override
+ public boolean propertyDeleted(PropertyState before) {
+ actual.append('-').append(before.getName());
+ return true;
+ }
+
+ @Override
+ public boolean childNodeAdded(String name, NodeState after) {
+ actual.append('+').append(name);
+ return true;
+ }
+
+ @Override
+ public boolean childNodeChanged(String name, NodeState before, NodeState after) {
+ actual.append('^').append(name);
+ return true;
+ }
+
+ @Override
+ public boolean childNodeDeleted(String name, NodeState before) {
+ actual.append('-').append(name);
+ return true;
+ }
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/SecureNodeStateDiffTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/SecureNodeStateDiffTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL