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=1768673&r1=1768672&r2=1768673&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
 Tue Nov  8 12:10:42 2016
@@ -29,6 +29,7 @@ import static org.apache.jackrabbit.oak.
 import java.security.Principal;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -40,6 +41,7 @@ import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeTypeIterator;
 import javax.jcr.observation.EventJournal;
 import javax.jcr.observation.EventListener;
 import javax.jcr.observation.EventListenerIterator;
@@ -62,6 +64,7 @@ import org.apache.jackrabbit.oak.plugins
 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.ChangeSetFilterImpl;
 import org.apache.jackrabbit.oak.plugins.observation.filter.Selectors;
 import org.apache.jackrabbit.oak.spi.commit.Observable;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
@@ -278,6 +281,7 @@ public class ObservationManagerImpl impl
 
         List<Condition> excludeConditions = createExclusions(filterBuilder, 
excludedPaths);
 
+        final String[] validatedNodeTypeNames = 
validateNodeTypeNames(nodeTypeName);
         Selector nodeTypeSelector = Selectors.PARENT;
         boolean deleteSubtree = true;
         if (oakEventFilter != null) {
@@ -304,7 +308,7 @@ public class ObservationManagerImpl impl
                     filterBuilder.moveSubtree(),
                     filterBuilder.eventType(eventTypes),
                     filterBuilder.uuid(Selectors.PARENT, uuids),
-                    filterBuilder.nodeType(nodeTypeSelector, 
validateNodeTypeNames(nodeTypeName)),
+                    filterBuilder.nodeType(nodeTypeSelector, 
validatedNodeTypeNames),
                     filterBuilder.accessControl(permissionProviderFactory));
         if (oakEventFilter != null) {
             condition = oakEventFilter.wrapMainCondition(condition, 
filterBuilder, permissionProviderFactory);
@@ -319,6 +323,32 @@ public class ObservationManagerImpl impl
         ListenerTracker tracker = new WarningListenerTracker(
                 !noExternal, listener, eventTypes, absPath, isDeep, uuids, 
nodeTypeName, noLocal);
 
+        if (oakEventFilter != null) {
+            oakEventFilter.adjustPrefilterIncludePaths(includePaths);
+        }
+        
+        // OAK-5082 : node type filtering should not only be direct but 
include derived types
+        // one easy way to solve this is to 'explode' the node types at start 
by including
+        // all subtypes of every registered node type
+        HashSet<String> explodedNodeTypes = null;
+        if (validatedNodeTypeNames != null) {
+            explodedNodeTypes = newHashSet();
+            for (String nt : validatedNodeTypeNames) {
+                NodeTypeIterator it = ntMgr.getNodeType(nt).getSubtypes();
+                while(it.hasNext()) {
+                    String subnt = String.valueOf(it.next());
+                    explodedNodeTypes.add(subnt);
+                }
+                explodedNodeTypes.add(nt);
+            }
+        }
+        
+        // OAK-4908 : prefiltering support. here we have explicit yes/no/maybe 
filtering
+        // for things like propertyNames/nodeTypes/nodeNames/paths which 
cannot be 
+        // applied on the full-fledged filterBuilder above but requires an 
explicit 'prefilter' for that.
+        filterBuilder.setChangeSetFilter(new ChangeSetFilterImpl(includePaths, 
isDeep, excludedPaths, null,
+                explodedNodeTypes, null));
+        
         addEventListener(listener, tracker, filterBuilder.build());
     }
 

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=1768673&r1=1768672&r2=1768673&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  8 12:10:42 2016
@@ -436,7 +436,25 @@ public class ObservationTest extends Abs
             observationManager.removeEventListener(listener);
         }
     }
+    
+    @Test
+    public void propertyFilter() throws Exception {
+        Node root = getNode("/");
+        ExpectationListener listener = new ExpectationListener();
+        observationManager.addEventListener(listener, PROPERTY_ADDED, "/a/b", 
false, null, null, false);
+        Node a = root.addNode("a");
+        Node b = a.addNode("b");
+        listener.expect("/a/b/jcr:primaryType", PROPERTY_ADDED);
 
+        listener.expectAdd(b.setProperty("propName", 1));
+       root.getSession().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());
+    }
+    
     @Test
     public void pathFilter() throws Exception {
         final String path = "/events/only/here";
@@ -1515,7 +1533,7 @@ public class ObservationTest extends Abs
 
         filter = new JackrabbitEventFilter();
         filter.setEventTypes(ALL_EVENTS);
-        filter = FilterFactory.wrap(filter).withIncludeGlobPaths(TEST_PATH + 
"/a3/**/y/*");
+        filter = FilterFactory.wrap(filter).withIncludeGlobPaths(TEST_PATH + 
"/a3/**/y");
         oManager.addEventListener(listener, filter);
         cp = oManager.getChangeProcessor(listener);
         assertNotNull(cp);


Reply via email to