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());
+    
+    }
+
+
 
 }


Reply via email to