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/07/10 14:35:11 UTC

svn commit: r1501751 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/

Author: mduerig
Date: Wed Jul 10 12:35:11 2013
New Revision: 1501751

URL: http://svn.apache.org/r1501751
Log:
OAK-144 Implement observation
Correctly offset id when path filter is set

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeDispatcher.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/ObservationTest.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=1501751&r1=1501750&r2=1501751&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 Wed Jul 10 12:35:11 2013
@@ -31,7 +31,11 @@ import javax.annotation.Nonnull;
 
 import com.google.common.collect.Queues;
 import com.google.common.collect.Sets;
+import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
@@ -250,6 +254,51 @@ public class ChangeDispatcher {
         public abstract long getDate();
 
         /**
+         * Get the id of the node at the given path as it was before this change set.
+         * @param path  path to determine the id for
+         * @return  id for the item at {@code path} or {@code path} if the item doesn't exit.
+         */
+        @Nonnull
+        public String getBeforeId(String path) {
+            return getId(before, path);
+        }
+
+        /**
+         * Get the id of the node at the given path as it is after this change set.
+         * @param path  path to determine the id for
+         * @return  id for the item at {@code path} or {@code path} if the item doesn't exit.
+         */
+        @Nonnull
+        public String getAfterId(String path) {
+            return getId(after, path);
+        }
+
+        private static String getId(NodeState nodeState, String path) {
+            StringBuilder id = new StringBuilder();
+
+            id.append(getIdOrName(nodeState, ""));
+            for (String name : PathUtils.elements(path)) {
+                nodeState = nodeState.getChildNode(name);
+                id.append('/').append(getIdOrName(nodeState, name));
+            }
+
+            if (id.length() == 0) {
+                return "/";
+            } else {
+                return id.toString();
+            }
+        }
+
+        private static String getIdOrName(NodeState nodeState, String name) {
+            PropertyState uuid = nodeState.getProperty(JcrConstants.JCR_UUID);
+            if (uuid == null) {
+                return name;
+            } else {
+                return uuid.getValue(Type.STRING);
+            }
+        }
+
+        /**
          * {@link NodeStateDiff} of the changes
          * @param diff  node state diff instance for traversing the changes.
          * @param path  path where diffing should start

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java?rev=1501751&r1=1501750&r2=1501751&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java Wed Jul 10 12:35:11 2013
@@ -259,7 +259,7 @@ class ChangeProcessor implements Runnabl
         @Override
         public boolean propertyAdded(PropertyState after) {
             if (filterRef.get().include(Event.PROPERTY_ADDED, path, afterParentNode)) {
-                Event event = generatePropertyEvent(Event.PROPERTY_ADDED, path, after, getAfterId());
+                Event event = generatePropertyEvent(Event.PROPERTY_ADDED, path, after, changes.getAfterId(path));
                 events.add(Iterators.singletonIterator(event));
             }
             return !stopping;
@@ -268,7 +268,7 @@ class ChangeProcessor implements Runnabl
         @Override
         public boolean propertyChanged(PropertyState before, PropertyState after) {
             if (filterRef.get().include(Event.PROPERTY_CHANGED, path, afterParentNode)) {
-                Event event = generatePropertyEvent(Event.PROPERTY_CHANGED, path, after, getAfterId());
+                Event event = generatePropertyEvent(Event.PROPERTY_CHANGED, path, after, changes.getAfterId(path));
                 events.add(Iterators.singletonIterator(event));
             }
             return !stopping;
@@ -277,7 +277,7 @@ class ChangeProcessor implements Runnabl
         @Override
         public boolean propertyDeleted(PropertyState before) {
             if (filterRef.get().include(Event.PROPERTY_REMOVED, path, afterParentNode)) {
-                Event event = generatePropertyEvent(Event.PROPERTY_REMOVED, path, before, getBeforeId());
+                Event event = generatePropertyEvent(Event.PROPERTY_REMOVED, path, before, changes.getBeforeId(path));
                 events.add(Iterators.singletonIterator(event));
             }
             return !stopping;
@@ -287,7 +287,7 @@ class ChangeProcessor implements Runnabl
         public boolean childNodeAdded(String name, NodeState after) {
             if (filterRef.get().includeChildren(path)) {
                 Iterator<Event> events = generateNodeEvents(Event.NODE_ADDED, path, name,
-                        after, afterParentNode, getAfterId(after, name));
+                        after, afterParentNode, changes.getAfterId(PathUtils.concat(path, name)));
                 this.events.add(events);
                 if (++childNodeCount > PURGE_LIMIT) {
                     sendEvents();
@@ -300,7 +300,7 @@ class ChangeProcessor implements Runnabl
         public boolean childNodeDeleted(String name, NodeState before) {
             if (filterRef.get().includeChildren(path)) {
                 Iterator<Event> events = generateNodeEvents(Event.NODE_REMOVED, path, name,
-                        before, beforeParentNode, getBeforeId(before, name));
+                        before, beforeParentNode, changes.getBeforeId(PathUtils.concat(path, name)));
                 this.events.add(events);
             }
             return !stopping;
@@ -331,53 +331,6 @@ class ChangeProcessor implements Runnabl
                     changes.isExternal());
         }
 
-        private String getRootId() {
-            // FIXME return id of root node if available
-            return "/";
-        }
-
-        private String getBeforeId(NodeState childNode, String childName) {
-            if (parent == null) {
-                return getRootId() + namePathMapper.getJcrName(childName);
-            }
-
-            PropertyState uuid = childNode.getProperty(JcrConstants.JCR_UUID);
-            if (uuid == null) {
-                return parent.getBeforeId(beforeParentNode, name) + '/' + namePathMapper.getJcrName(childName);
-            }
-
-            return uuid.getValue(Type.STRING);
-        }
-
-        private String getAfterId(NodeState childNode, String childName) {
-            if (parent == null) {
-                return getRootId() + namePathMapper.getJcrName(childName);
-            }
-
-            PropertyState uuid = childNode.getProperty(JcrConstants.JCR_UUID);
-            if (uuid == null) {
-                return parent.getAfterId(afterParentNode, name) + '/' + namePathMapper.getJcrName(childName);
-            }
-
-            return uuid.getValue(Type.STRING);
-        }
-
-        private String getBeforeId() {
-            if (parent == null) {
-                return getRootId();
-            } else {
-                return parent.getBeforeId(beforeParentNode, name);
-            }
-        }
-
-        private String getAfterId() {
-            if (parent == null) {
-                return getRootId();
-            } else {
-                return parent.getBeforeId(beforeParentNode, name);
-            }
-        }
-
         private Event generatePropertyEvent(int eventType, String parentPath, PropertyState property, String id) {
             String path = PathUtils.concat(parentPath, property.getName());
             return createEvent(eventType, path, id);

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/ObservationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/ObservationTest.java?rev=1501751&r1=1501750&r2=1501751&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/ObservationTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/ObservationTest.java Wed Jul 10 12:35:11 2013
@@ -155,6 +155,32 @@ public class ObservationTest extends Abs
     }
 
     @Test
+    public void identifier() throws RepositoryException, InterruptedException, ExecutionException {
+        ExpectationListener listener = new ExpectationListener();
+        observationManager.addEventListener(listener, NODE_ADDED, TEST_PATH, true, null, null, false);
+        try {
+            Node n = getNode(TEST_PATH);
+            listener.expect(new Expectation("Has correct id") {
+                @Override
+                public boolean onEvent(Event event) throws Exception {
+                    return (TEST_PATH + "/newNode").equals(event.getIdentifier());
+                }
+            });
+
+            n.addNode("newNode");
+            getAdminSession().save();
+
+            List<Expectation> missing = listener.getMissing(2, TimeUnit.SECONDS);
+            assertTrue("Missing events: " + missing, missing.isEmpty());
+            List<Event> unexpected = listener.getUnexpected();
+            assertTrue("Unexpected events: " + unexpected, unexpected.isEmpty());
+        }
+        finally {
+            observationManager.removeEventListener(listener);
+        }
+    }
+
+    @Test
     public void observationOnRootNode() throws Exception {
         ExpectationListener listener = new ExpectationListener();
         observationManager.addEventListener(listener, PROPERTY_ADDED, "/", true, null, null, false);