jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r1539044 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/ObservationTest.java
Date Tue, 05 Nov 2013 16:16:45 GMT
Author: mduerig
Date: Tue Nov  5 16:16:45 2013
New Revision: 1539044

URL: http://svn.apache.org/r1539044
Log:
OAK-1090: Event-listener not notified on Node.orderBefore
Initial implementation generating the move events from looking at the differences in the :childOrder
property of the parent node

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.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/EventGenerator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java?rev=1539044&r1=1539043&r2=1539044&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java
Tue Nov  5 16:16:45 2013
@@ -26,7 +26,9 @@ import static javax.jcr.observation.Even
 import static javax.jcr.observation.Event.NODE_REMOVED;
 import static javax.jcr.observation.Event.PROPERTY_ADDED;
 import static javax.jcr.observation.Event.PROPERTY_REMOVED;
+import static org.apache.jackrabbit.oak.api.Type.STRING;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
+import static org.apache.jackrabbit.oak.core.AbstractTree.OAK_CHILD_ORDER;
 import static org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager.getIdentifier;
 
 import java.util.Iterator;
@@ -38,6 +40,7 @@ import javax.jcr.observation.Event;
 import com.google.common.collect.ForwardingIterator;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree;
@@ -178,12 +181,53 @@ class EventGenerator extends ForwardingI
 
     @Override
     public MoveValidator childNodeChanged(String name, NodeState before, NodeState after)
{
+        if (filter.include(NODE_MOVED, afterTree)) {
+            detectReorder(name, before, after);
+        }
         if (filter.includeChildren(afterTree.getPath())) {
             childEvents.add(new EventGenerator(this, name));
         }
         return null;
     }
 
+    private void detectReorder(String name, NodeState before, NodeState after) {
+        PropertyState afterOrder = after.getProperty(OAK_CHILD_ORDER);
+        PropertyState beforeOrder = before.getProperty(OAK_CHILD_ORDER);
+        if (afterOrder == null || beforeOrder == null) {
+            return;
+        }
+
+        List<String> afterNames = getNames(afterOrder);
+        List<String> beforeNames = getNames(beforeOrder);
+
+        afterNames.retainAll(beforeNames);
+        beforeNames.retainAll(afterNames);
+
+        // Selection sort beforeNames into afterNames recording the swaps as we go
+        for (int a = 0; a < afterNames.size(); a++) {
+            String afterName = afterNames.get(a);
+            for (int b = a; b < beforeNames.size(); b++) {
+                String beforeName = beforeNames.get(b);
+                if (a != b && beforeName.equals(afterName)) {
+                    beforeNames.set(b, beforeNames.get(a));
+                    beforeNames.set(a, beforeName);
+                    events.add(createEvent(NODE_MOVED, afterTree.getChild(name).getChild(afterName),
+                            ImmutableMap.of(
+                                    "srcChildRelPath", beforeNames.get(a),
+                                    "destChildRelPath", beforeNames.get(a + 1))));
+                }
+            }
+        }
+    }
+
+    private static List<String> getNames(PropertyState propertyState) {
+        List<String> names = Lists.newArrayList();
+        for (int k = 0; k < propertyState.count(); k++) {
+            names.add(propertyState.getValue(STRING, k));
+        }
+        return names;
+    }
+
     @Override
     public void move(String sourcePath, String destPath, NodeState moved)
             throws CommitFailedException {

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=1539044&r1=1539043&r2=1539044&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
Tue Nov  5 16:16:45 2013
@@ -31,6 +31,7 @@ import static org.junit.Assert.assertNot
 import static org.junit.Assert.assertTrue;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -288,7 +289,7 @@ public class ObservationTest extends Abs
             }
         });
 
-        observationManager.addEventListener(listener, NODE_ADDED, path + "/", true, null,
null, false);
+        observationManager.addEventListener(listener, NODE_ADDED, path + '/', true, null,
null, false);
         try {
             Node root = getNode("/");
             root.addNode("events").addNode("only").addNode("here").addNode("at");
@@ -380,6 +381,44 @@ public class ObservationTest extends Abs
         assertFalse(observationManager.getRegisteredEventListeners().hasNext());
     }
 
+    @Test
+    public void testReorder() throws RepositoryException, InterruptedException, ExecutionException
{
+        Node testNode = getNode(TEST_PATH);
+        Node nodeA = testNode.addNode("a", "nt:unstructured");
+        Node nodeB = testNode.addNode("b", "nt:unstructured");
+        testNode.getSession().save();
+
+        ExpectationListener listener = new ExpectationListener();
+        observationManager.addEventListener(listener, Event.NODE_MOVED, "/", true, null,
null, false);
+        listener.expect(new Expectation("orderBefore"){
+            @Override
+            public boolean onEvent(Event event) throws Exception {
+                if (event.getType() != NODE_MOVED || event.getInfo() == null) {
+                    return false;
+                }
+
+                Map<?, ?> info = event.getInfo();
+                if (PathUtils.concat(TEST_PATH, "a").equals(event.getPath())) {
+                    return "a".equals(info.get("srcChildRelPath")) &&
+                           "b".equals(info.get("destChildRelPath"));
+                } else if (PathUtils.concat(TEST_PATH, "b").equals(event.getPath())) {
+                    return "b".equals(info.get("srcChildRelPath")) &&
+                           "a".equals(info.get("destChildRelPath"));
+                } else {
+                    return false;
+                }
+            }
+        });
+
+        testNode.orderBefore(nodeA.getName(), null);
+        testNode.getSession().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());
+    }
+
     //------------------------------------------------------------< private >---
 
     private Node getNode(String path) throws RepositoryException {



Mime
View raw message