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 2014/04/02 16:32:01 UTC

svn commit: r1584053 - in /jackrabbit/oak/trunk: oak-doc/src/site/markdown/ oak-jcr/ 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 Apr  2 14:32:01 2014
New Revision: 1584053

URL: http://svn.apache.org/r1584053
Log:
OAK-1661: JCR Event Info should contain NodeType for Events Type Node-Deleted
pass primary and mixin types of added and removed nodes through the event's info map

Modified:
    jackrabbit/oak/trunk/oak-doc/src/site/markdown/differences.md
    jackrabbit/oak/trunk/oak-jcr/pom.xml
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/ObservationTest.java

Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/differences.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/differences.md?rev=1584053&r1=1584052&r2=1584053&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/differences.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/differences.md Wed Apr  2 14:32:01 2014
@@ -84,6 +84,10 @@ See the [query overview page](query.html
 
 Observation
 -----------
+* `Event.getInfo()` contains the primary and mixin node types of the added/removed node
+   in the case of `Event.NODE_ADDED` and `Event.NODE_REMOVED`. The key `jcr:primaryType`
+   maps to the primary type and the key `jcr:mixinTypes` maps to an array containing
+   the mixin types.
 
 * `Event.getUserId()`, `Event.getUserData()`and `Event.getDate()` will only be available for locally
   generated events (i.e. on the same cluster node). To help identifying potential trouble spots,

Modified: jackrabbit/oak/trunk/oak-jcr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/pom.xml?rev=1584053&r1=1584052&r2=1584053&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-jcr/pom.xml Wed Apr  2 14:32:01 2014
@@ -69,6 +69,8 @@
       org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testImplicitUnlock2
 
       <!-- Observation -->
+      org.apache.jackrabbit.test.api.observation.GetInfoTest#testNodeAdded              <!-- OAK-1661 -->
+      org.apache.jackrabbit.test.api.observation.GetInfoTest#testNodeRemoved            <!-- OAK-1661 -->
       org.apache.jackrabbit.test.api.observation.NodeRemovedTest#testMultiNodesRemoved  <!-- OAK-1459 -->
       org.apache.jackrabbit.test.api.observation.NodeMovedTest#testMoveWithRemove       <!-- OAK-1459 -->
       org.apache.jackrabbit.test.api.observation.GetIdentifierTest#testNodeMoved  <!-- Move in 2nd session not reflected in nodes of 1st session -->

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java?rev=1584053&r1=1584052&r2=1584053&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java Wed Apr  2 14:32:01 2014
@@ -18,20 +18,25 @@
  */
 package org.apache.jackrabbit.oak.jcr.observation;
 
+import static com.google.common.collect.Iterables.isEmpty;
+import static com.google.common.collect.Iterables.toArray;
 import static java.util.Collections.emptyMap;
+import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
 
+import java.util.List;
 import java.util.Map;
 
 import javax.jcr.observation.Event;
 
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
 import org.apache.jackrabbit.api.observation.JackrabbitEvent;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableMap;
-
 /**
  * Event factory for generating JCR event instances that are optimized
  * for minimum memory overhead. Each factory instance keeps track of the
@@ -97,21 +102,46 @@ public class EventFactory {
         };
     }
 
-    Event nodeAdded(String path, String name, String identifier) {
+    private Map<String, ?> createInfoMap(String primaryType, Iterable<String> mixinTypes) {
+        if (isEmpty(mixinTypes)) {
+            return ImmutableMap.of(
+                    JCR_PRIMARYTYPE, mapper.getJcrName(primaryType));
+        } else {
+            List<String> jcrNames = Lists.newArrayList();
+            for (String name : mixinTypes) {
+                jcrNames.add(mapper.getJcrName(name));
+            }
+            return ImmutableMap.of(
+                    JCR_PRIMARYTYPE, mapper.getJcrName(primaryType),
+                    JCR_MIXINTYPES, toArray(jcrNames, String.class));
+        }
+    }
+
+    Event nodeAdded(final String primaryType, final Iterable<String> mixinTypes,
+            String path, String name, String identifier) {
         return new EventImpl(path, name, identifier) {
             @Override
             public int getType() {
                 return NODE_ADDED;
             }
+            @Override
+            public Map<?, ?> getInfo() {
+                return createInfoMap(primaryType, mixinTypes);
+            }
         };
     }
 
-    Event nodeDeleted(String path, String name, String identifier) {
+    Event nodeDeleted(final String primaryType, final Iterable<String> mixinTypes,
+            String path, String name, String identifier) {
         return new EventImpl(path, name, identifier) {
             @Override
             public int getType() {
                 return NODE_REMOVED;
             }
+            @Override
+            public Map<?, ?> getInfo() {
+                return createInfoMap(primaryType, mixinTypes);
+            }
         };
     }
 

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java?rev=1584053&r1=1584052&r2=1584053&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/QueueingHandler.java Wed Apr  2 14:32:01 2014
@@ -18,6 +18,12 @@
  */
 package org.apache.jackrabbit.oak.jcr.observation;
 
+import static java.util.Collections.emptyList;
+import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.NAMES;
+
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.namepath.PathTracker;
 import org.apache.jackrabbit.oak.plugins.identifier.IdentifierTracker;
@@ -103,11 +109,30 @@ class QueueingHandler extends DefaultEve
                 identifierTracker.getIdentifier()));
     }
 
+    private static String getPrimaryType(NodeState before) {
+        PropertyState primaryType = before.getProperty(JCR_PRIMARYTYPE);
+        if (primaryType != null && primaryType.getType() == NAME) {
+            return primaryType.getValue(NAME);
+        } else {
+            return null;
+        }
+    }
+
+    private static Iterable<String> getMixinTypes(NodeState before) {
+        PropertyState mixinTypes = before.getProperty(JCR_MIXINTYPES);
+        if (mixinTypes != null && mixinTypes.getType() == NAMES) {
+            return mixinTypes.getValue(NAMES);
+        } else {
+            return emptyList();
+        }
+    }
+
     @Override
     public void nodeAdded(String name, NodeState after) {
         IdentifierTracker tracker =
                 identifierTracker.getChildTracker(name, after);
         queue.addEvent(factory.nodeAdded(
+                getPrimaryType(after), getMixinTypes(after),
                 pathTracker.getPath(), name, tracker.getIdentifier()));
     }
 
@@ -115,7 +140,9 @@ class QueueingHandler extends DefaultEve
     public void nodeDeleted(String name, NodeState before) {
         IdentifierTracker tracker =
                 beforeIdentifierTracker.getChildTracker(name, before);
+
         queue.addEvent(factory.nodeDeleted(
+                getPrimaryType(before), getMixinTypes(before),
                 pathTracker.getPath(), name, tracker.getIdentifier()));
     }
 

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=1584053&r1=1584052&r2=1584053&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 Apr  2 14:32:01 2014
@@ -28,6 +28,9 @@ import static javax.jcr.observation.Even
 import static javax.jcr.observation.Event.PROPERTY_ADDED;
 import static javax.jcr.observation.Event.PROPERTY_CHANGED;
 import static javax.jcr.observation.Event.PROPERTY_REMOVED;
+import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
 import static org.apache.jackrabbit.oak.api.Type.STRING;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -157,6 +160,65 @@ public class ObservationTest extends Abs
     }
 
     @Test
+    public void infoMap() throws RepositoryException, ExecutionException, InterruptedException {
+        ExpectationListener listener = new ExpectationListener();
+        observationManager.addEventListener(listener, NODE_ADDED, "/", true, null, null, false);
+        try {
+            Node n = getNode(TEST_PATH);
+            n.addNode("n1", "oak:Unstructured");
+            n.addNode("n2");
+            n.getNode("n2").addMixin(TEST_TYPE);
+
+            listener.expect(new Expectation("infoMap for n1") {
+                @Override
+                public boolean onEvent(Event event) throws Exception {
+                    if (event.getPath().endsWith("n1")) {
+                        Map<?, ?> info = event.getInfo();
+                        return info != null &&
+                                "oak:Unstructured".equals(info.get(JCR_PRIMARYTYPE));
+                    } else {
+                        return false;
+                    }
+                }
+            });
+
+            listener.expect(new Expectation("infoMap for n2") {
+                @Override
+                public boolean onEvent(Event event) throws Exception {
+                    if (event.getPath().endsWith("n2")) {
+                        Map<?, ?> info = event.getInfo();
+                        if (info == null) {
+                            return false;
+                        }
+                        Object mixinTypes = info.get(JCR_MIXINTYPES);
+                        if (!(mixinTypes instanceof String[])) {
+                            return false;
+                        }
+
+                        Object primaryType = info.get(JCR_PRIMARYTYPE);
+                        String[] mixins = (String[]) mixinTypes;
+                        return NT_UNSTRUCTURED.equals(primaryType) &&
+                                mixins.length == 1 &&
+                                TEST_TYPE.equals(mixins[0]);
+                    } else {
+                        return false;
+                    }
+                }
+            });
+
+            getAdminSession().save();
+
+            List<Expectation> missing = listener.getMissing(TIME_OUT, 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 observation2() throws RepositoryException, InterruptedException, ExecutionException {
         ExpectationListener listener = new ExpectationListener();
         observationManager.addEventListener(listener, ALL_EVENTS, "/", true, null, null, false);