Author: stefanegli
Date: Mon Oct 31 12:57:38 2016
New Revision: 1767266
URL: http://svn.apache.org/viewvc?rev=1767266&view=rev
Log:
OAK-5023 : introducing applyNodeTypeOnSelf feature which changes the way the
node type filter is applied: normally on the parent, with this switch on
own==self now, where the change actually happened
Modified:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/filter/OakEventFilter.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/ObservationTest.java
Modified:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImpl.java?rev=1767266&r1=1767265&r2=1767266&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImpl.java
Mon Oct 31 12:57:38 2016
@@ -32,6 +32,9 @@ import org.apache.jackrabbit.oak.jcr.obs
public class OakEventFilterImpl extends OakEventFilter {
private final JackrabbitEventFilter delegate;
+
+ /** whether or not applyNodeTypeOnSelf feature is enabled */
+ private boolean applyNodeTypeOnSelf;
public OakEventFilterImpl(@Nonnull JackrabbitEventFilter delegate) {
checkNotNull(delegate);
@@ -148,4 +151,14 @@ public class OakEventFilterImpl extends
return this;
}
+ @Override
+ public OakEventFilter withApplyNodeTypeOnSelf() {
+ this.applyNodeTypeOnSelf = true;
+ return this;
+ }
+
+ boolean getApplyNodeTypeOnSelf() {
+ return applyNodeTypeOnSelf;
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java?rev=1767266&r1=1767265&r2=1767266&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
Mon Oct 31 12:57:38 2016
@@ -56,6 +56,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.observation.ExcludeExternal;
import org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder;
import
org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder.Condition;
+import
org.apache.jackrabbit.oak.plugins.observation.filter.UniversalFilter.Selector;
import org.apache.jackrabbit.oak.plugins.observation.filter.FilterProvider;
import
org.apache.jackrabbit.oak.plugins.observation.filter.PermissionProviderFactory;
import org.apache.jackrabbit.oak.plugins.observation.filter.Selectors;
@@ -208,6 +209,10 @@ public class ObservationManagerImpl impl
@Override
public void addEventListener(EventListener listener, JackrabbitEventFilter
filter)
throws RepositoryException {
+ OakEventFilterImpl oakEventFilter = null;
+ if (filter instanceof OakEventFilterImpl) {
+ oakEventFilter = (OakEventFilterImpl) filter;
+ }
int eventTypes = filter.getEventTypes();
boolean isDeep = filter.getIsDeep();
@@ -238,6 +243,13 @@ public class ObservationManagerImpl impl
List<Condition> excludeConditions = createExclusions(filterBuilder,
excludedPaths);
+ Selector nodeTypeSelector = Selectors.PARENT;
+ if (oakEventFilter != null) {
+ if (oakEventFilter.getApplyNodeTypeOnSelf()) {
+ nodeTypeSelector = Selectors.THIS;
+ }
+ }
+
filterBuilder
.includeSessionLocal(!noLocal)
.includeClusterExternal(!noExternal)
@@ -249,7 +261,7 @@ public class ObservationManagerImpl impl
filterBuilder.moveSubtree(),
filterBuilder.eventType(eventTypes),
filterBuilder.uuid(Selectors.PARENT, uuids),
- filterBuilder.nodeType(Selectors.PARENT,
validateNodeTypeNames(nodeTypeName)),
+ filterBuilder.nodeType(nodeTypeSelector,
validateNodeTypeNames(nodeTypeName)),
filterBuilder.accessControl(permissionProviderFactory)));
// FIXME support multiple path in ListenerTracker
Modified:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/filter/OakEventFilter.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/filter/OakEventFilter.java?rev=1767266&r1=1767265&r2=1767266&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/filter/OakEventFilter.java
(original)
+++
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/filter/OakEventFilter.java
Mon Oct 31 12:57:38 2016
@@ -34,4 +34,16 @@ import aQute.bnd.annotation.ConsumerType
@ConsumerType
public abstract class OakEventFilter extends JackrabbitEventFilter {
+ /**
+ * This causes the node type filter to be applied on 'this' node instead of
+ * the 'parent' node, thus allows to create a filter which listens on
+ * adding/removing/etc on nodes of a particular node type (while the
default
+ * was that the node type was applicable on the parent).
+ * <p>
+ * Note that this is an 'either/or' thing: either the node type is applied
+ * on the parent (default) or on 'self/this' (via this switch) but not
both.
+ * @return this filter with the filter change applied
+ */
+ public abstract OakEventFilter withApplyNodeTypeOnSelf();
+
}
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=1767266&r1=1767265&r2=1767266&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
Mon Oct 31 12:57:38 2016
@@ -78,6 +78,7 @@ import org.apache.jackrabbit.oak.api.Pro
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.fixture.NodeStoreFixture;
import org.apache.jackrabbit.oak.jcr.AbstractRepositoryTest;
+import org.apache.jackrabbit.oak.jcr.observation.filter.FilterFactory;
import org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder;
import org.apache.jackrabbit.oak.plugins.observation.filter.Selectors;
import org.junit.After;
@@ -1233,5 +1234,48 @@ public class ObservationTest extends Abs
return path + ':' + type;
}
}
+
+ @Test
+ public void applyNodeTypeOnSelf() throws Exception {
+ assumeTrue(observationManager instanceof ObservationManagerImpl);
+
+ Node testNode = getNode(TEST_PATH);
+ testNode.addNode("a", "nt:unstructured").addNode("b",
"oak:Unstructured").addNode("c", "nt:unstructured");
+ testNode.getSession().save();
+
+ ObservationManagerImpl oManager = (ObservationManagerImpl)
observationManager;
+ ExpectationListener listener = new ExpectationListener();
+
+ JackrabbitEventFilter filter = new JackrabbitEventFilter();
+ filter.setEventTypes(ALL_EVENTS);
+ filter.setAbsPath("/");
+ filter.setIsDeep(true);
+ filter.setNodeTypes(new String[] {"oak:Unstructured"});
+ filter = FilterFactory.wrap(filter).withApplyNodeTypeOnSelf();
+
+ oManager.addEventListener(listener, filter);
+
+ testNode.getNode("a").getNode("b").getNode("c").remove();
+ testNode.getSession().save();
+
+ // wait 1 sec to give failures a chance (we're not expecting anything,
but perhaps
+ // something would come, after 1sec more likely than after 0sec)
+ Thread.sleep(1000);
+ 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());
+
+ testNode.getNode("a").getNode("b").remove();
+ testNode.getSession().save();
+
+ missing = listener.getMissing(TIME_OUT, TimeUnit.SECONDS);
+ assertTrue("Missing events: " + missing, missing.isEmpty());
+ unexpected = listener.getUnexpected();
+ assertTrue("Unexpected events: " + unexpected, unexpected.isEmpty());
+
+ }
+
+
}