Author: stefanegli
Date: Mon Feb 13 15:58:42 2017
New Revision: 1782797

URL: http://svn.apache.org/viewvc?rev=1782797&view=rev
Log:
OAK-5619 : fixing withIncludeAncestorsRemove which reported /unrelated parent 
NODE_REMOVEs

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/filter/OakEventFilter.java
    
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImplTest.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=1782797&r1=1782796&r2=1782797&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 Feb 13 15:58:42 2017
@@ -384,35 +384,47 @@ public class OakEventFilterImpl extends
         return includeAncestorRemove;
     }
 
+    /**
+     * This helper method goes through the provided globPath and adds
+     * each parent (ancestor)'s path to the ancestorPaths set.
+     * <p>
+     * OAK-5619 : this used to add "${parent}/*" type ancestor paths, however
+     * that was wrong: we must only take the actual "${parent}"s to which we 
want
+     * to listen to. Also, the glob case looks slightly different than 
originally
+     * implemented:
+     * <ul>
+     *  <li>* : we treat this as a normal name, ie as a normal parent and 
continue normally</li>
+     *  <li>**: when a ** is hit, the loop through the elements can be stopped,
+     *  as ** includes all children already, so no further paths are 
needed.</li>
+     * </ul>
+     * @param ancestorPaths the set to which the ancestors of globPath will
+     * be added to
+     * @param globPath the input path that may contain globs
+     */
     static void addAncestorPaths(Set<String> ancestorPaths, String globPath) {
         if (globPath == null || !globPath.contains("/")) {
             return;
         }
-        // from /a/b/c         => add /*, /a/* and /a/b/*
-        // from /a/b/**        => add /*, /a/*
-        // from /a             => add /*, nothing
+        // from /a/b/c         => add /a, /a/b, /a/b/c
+        // from /a/b/**        => add /a, /a/b, /a/b/**
+        // from /a             => add /a
         // from /              => add nothing
-        // from /a/b/**/*.html => add /*, /a/*
-        // from /a/b/*/*.html  => add /*, /a/*
+        // from /a/b/**/*.html => add /a, /a/b, /a/b/**
+        // from /a/b/*/*.html  => add /a, /a/b, /a/b/*, /a/b/*/*.html
+        // from /a/b/*/d       => add /a, /a/b, /a/b/*, /a/b/*/d
+        // from /a/b/*/d/e     => add /a, /a/b, /a/b/*, /a/b/*/d, /a/b/*/d/e
 
         Iterator<String> it = PathUtils.elements(globPath).iterator();
         StringBuffer sb = new StringBuffer();
-        if (it.hasNext()) {
-            ancestorPaths.add("/*");
-        }
         while(it.hasNext()) {
             String element = it.next();
-            if (element.contains("*")) {
-                if (ancestorPaths.size() > 0) {
-                    ancestorPaths.remove(ancestorPaths.size()-1);
-                }
-                break;
-            } else if (!it.hasNext()) {
-                break;
-            }
             sb.append("/");
             sb.append(element);
-            ancestorPaths.add(sb.toString() + "/*");
+            ancestorPaths.add(sb.toString());
+            if (element.equals("**")) {
+                // then we can stop as ** contains everything already
+                break;
+            }
         }
     }
 

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=1782797&r1=1782796&r2=1782797&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 Feb 13 15:58:42 2017
@@ -61,7 +61,14 @@ public abstract class OakEventFilter ext
      * <li>include path /a/b/c/d results in additional !deep NODE_REMOVED
      * filters on /a/b/c, on /a/b and on /a</li>
      * <li>include path /a/b/** results in additional !deep NODE_REMOVED
-     * filter on /a</li>
+     * filter on /a, /a/b and /a/b/**</li>
+     * <li>include path /a/b/**{@code /}*.jsp results in additional 
+     * deep NODE_REMOVED filter on /a, /a/b and /a/b/** <br/>
+     * Note that this and the above result in the same additional
+     * include paths since all this includeAncestorsRemove flag 
+     * does is include potential ancestors, it doesn't guarantee 
+     * that there are children matching the given paths (eg it doesn't
+     * traverse down)</li>
      * <li>additionally for paths with globs (eg /a/b/**{@code /}*.jsp)
      * it adds a deep NODE_REMOVED filter explicitly for that path
      * using the same method as withIncludeSubtreeOnRemove does, but only

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImplTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImplTest.java?rev=1782797&r1=1782796&r2=1782797&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImplTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/observation/OakEventFilterImplTest.java
 Mon Feb 13 15:58:42 2017
@@ -33,17 +33,20 @@ public class OakEventFilterImplTest {
         assertMatches(new String[] {}, "/");
         
         assertMatches(new String[] {"/*"}, "/*");
-        assertMatches(new String[] {"/*"}, "/**");
-        assertMatches(new String[] {"/*"}, "/a");
-        assertMatches(new String[] {"/*", "/a/*"}, "/a/b");
-        assertMatches(new String[] {"/*", "/a/*"}, "/a/*");
-        assertMatches(new String[] {"/*", "/a/*"}, "/a/**");
-        assertMatches(new String[] {"/*", "/a/*", "/a/b/*"}, "/a/b/c");
-        assertMatches(new String[] {"/*", "/a/*", "/a/b/*"}, "/a/b/*");
-        assertMatches(new String[] {"/*", "/a/*", "/a/b/*"}, "/a/b/**");
-        assertMatches(new String[] {"/*", "/a/*", "/a/b/*", "/a/b/c/*"}, 
"/a/b/c/d");
-        assertMatches(new String[] {"/*", "/a/*", "/a/b/*", "/a/b/c/*"}, 
"/a/b/c/*");
-        assertMatches(new String[] {"/*", "/a/*", "/a/b/*", "/a/b/c/*"}, 
"/a/b/c/**");
+        assertMatches(new String[] {"/**"}, "/**");
+        assertMatches(new String[] {"/a"}, "/a");
+        assertMatches(new String[] {"/a", "/a/b"}, "/a/b");
+        assertMatches(new String[] {"/a", "/a/*"}, "/a/*");
+        assertMatches(new String[] {"/a", "/a/**"}, "/a/**");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/c"}, "/a/b/c");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/*"}, "/a/b/*");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/**"}, "/a/b/**");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/**"}, "/a/b/**/d");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/**"}, "/a/b/**/d/**");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/**"}, 
"/a/b/**/d/**/f");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/c", "/a/b/c/d"}, 
"/a/b/c/d");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/c", "/a/b/c/*"}, 
"/a/b/c/*");
+        assertMatches(new String[] {"/a", "/a/b", "/a/b/c", "/a/b/c/**"}, 
"/a/b/c/**");
     }
 
     private void assertMatches(String[] expectedPaths, String globPath) {

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=1782797&r1=1782796&r2=1782797&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 Feb 13 15:58:42 2017
@@ -108,7 +108,6 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.observation.filter.Selectors;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -1547,7 +1546,6 @@ public class ObservationTest extends Abs
      * NOT to get any event if an unrelated parent is removed
      */
     @Test
-    @Ignore("OAK-5619")
     public void includeAncestorsRemove_Unrelated() throws Exception {
         doIncludeAncestorsRemove_Unrelated(
                 new String[] {"/a/b/c/d"}, 
@@ -2299,7 +2297,7 @@ public class ObservationTest extends Abs
         oef.withIncludeAncestorsRemove()
                 .withNodeTypeAggregate(new String[] { "oak:Unstructured" }, 
new String[] { "", "jcr:content" } )
                 .withIncludeGlobPaths("/**/*.jsp");
-        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/*", 
"/**/*.jsp", "/**/*.jsp/**"});
+        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/**", 
"/**/*.jsp", "/**/*.jsp/**"});
 
         oef = FilterFactory.wrap(new JackrabbitEventFilter());
         oef.setEventTypes(ALL_EVENTS);
@@ -2307,14 +2305,14 @@ public class ObservationTest extends Abs
         oef.withIncludeAncestorsRemove()
                 .withNodeTypeAggregate(new String[] { "oak:Unstructured" }, 
new String[] { "", "jcr:content" } )
                 .withIncludeGlobPaths("/**/*.jsp");
-        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/*", 
"/**/*.jsp", "/**/*.jsp/**"});
+        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/**", 
"/**/*.jsp", "/**/*.jsp/**"});
         
         oef = FilterFactory.wrap(new JackrabbitEventFilter());
         oef.setEventTypes(ALL_EVENTS);
         oef.withIncludeAncestorsRemove()
                 .withNodeTypeAggregate(new String[] { "oak:Unstructured" }, 
new String[] { "", "jcr:content" } )
                 .withIncludeGlobPaths("**/*.jsp");
-        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/*", 
"**/*.jsp", "**/*.jsp/**"});
+        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/**", 
"**/*.jsp", "**/*.jsp/**"});
 
         oef = FilterFactory.wrap(new JackrabbitEventFilter());
         oef.setEventTypes(ALL_EVENTS);
@@ -2335,7 +2333,14 @@ public class ObservationTest extends Abs
         oef.withIncludeAncestorsRemove()
                 .withNodeTypeAggregate(new String[] { "oak:Unstructured" }, 
new String[] { "", "jcr:content" } )
                 .withIncludeGlobPaths("/parent/**/*.jsp");
-        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/*", 
"/parent/*", "/parent/**/*.jsp", "/parent/**/*.jsp/**"});
+        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/parent", 
"/parent/**", "/parent/**/*.jsp", "/parent/**/*.jsp/**"});
+        
+        oef = FilterFactory.wrap(new JackrabbitEventFilter());
+        oef.setEventTypes(ALL_EVENTS);
+        oef.withIncludeAncestorsRemove()
+                .withNodeTypeAggregate(new String[] { "oak:Unstructured" }, 
new String[] { "", "jcr:content" } )
+                .withIncludeGlobPaths("/parent/bar/**/*.jsp");
+        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/parent", 
"/parent/bar", "/parent/bar/**", "/parent/bar/**/*.jsp", 
"/parent/bar/**/*.jsp/**"});
         
         oef = FilterFactory.wrap(new JackrabbitEventFilter());
         oef.setEventTypes(ALL_EVENTS);
@@ -2356,7 +2361,7 @@ public class ObservationTest extends Abs
         oef.withIncludeAncestorsRemove()
                 .withNodeTypeAggregate(new String[] { "oak:Unstructured" }, 
new String[] { "", "jcr:content" } )
                 .withIncludeGlobPaths("/parent/**/*.jsp", "/foo/bar/**");
-        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/*", 
"/foo/*", "/foo/bar/*", "/foo/bar/**", "/parent/*", "/parent/**/*.jsp", 
"/parent/**/*.jsp/**"});
+        doTestAggregate6(oef, new String[] {"/"}, new String[] {"/parent", 
"/foo", "/foo/bar", "/foo/bar/**", "/parent/**", "/parent/**/*.jsp", 
"/parent/**/*.jsp/**"});
     }
 
     private void doTestAggregate6(OakEventFilter oef, String[] 
expectedSubTrees, String[] expectedPrefilterPaths)


Reply via email to