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);