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 st...@apache.org on 2016/10/31 16:59:32 UTC
svn commit: r1767330 - in /jackrabbit/oak/trunk/oak-jcr/src:
main/java/org/apache/jackrabbit/oak/jcr/observation/
main/java/org/apache/jackrabbit/oak/jcr/observation/filter/
test/java/org/apache/jackrabbit/oak/jcr/observation/
Author: stefanegli
Date: Mon Oct 31 16:59:32 2016
New Revision: 1767330
URL: http://svn.apache.org/viewvc?rev=1767330&view=rev
Log:
OAK-5019 : introducing support for glob include paths to the OakEventFilter
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=1767330&r1=1767329&r2=1767330&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 16:59:32 2016
@@ -54,6 +54,8 @@ public class OakEventFilterImpl extends
/** whether or not includeSubTreeOnRemove feature is enabled */
private boolean includeSubtreeOnRemove;
+ private String[] globPaths;
+
public OakEventFilterImpl(@Nonnull JackrabbitEventFilter delegate) {
checkNotNull(delegate);
this.delegate = delegate;
@@ -229,11 +231,11 @@ public class OakEventFilterImpl extends
addAncestorsRemoveCondition(parentPaths, absPath);
}
}
-// if (globPaths != null) {
-// for (String globPath : globPaths) {
-// addAncestorsRemoveCondition(parentPaths, globPath);
-// }
-// }
+ if (globPaths != null) {
+ for (String globPath : globPaths) {
+ addAncestorsRemoveCondition(parentPaths, globPath);
+ }
+ }
if (parentPaths.size() == 0) {
return mainCondition;
}
@@ -262,4 +264,20 @@ public class OakEventFilterImpl extends
return includeSubtreeOnRemove;
}
+ @Override
+ public OakEventFilter withIncludeGlobPaths(String... globPaths) {
+ if (this.globPaths != null) {
+ throw new IllegalStateException("can only set globPaths once");
+ }
+// for (String aGlobPath : globPaths) {
+// return or(builder().path(aGlobPath));
+// }
+ this.globPaths = globPaths;
+ return this;
+ }
+
+ String[] getIncludeGlobPaths() {
+ return globPaths;
+ }
+
}
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=1767330&r1=1767329&r2=1767330&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 16:59:32 2016
@@ -22,11 +22,14 @@ import static com.google.common.collect.
import static com.google.common.collect.Sets.newHashSet;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
+import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
import static org.apache.jackrabbit.oak.plugins.observation.filter.GlobbingPathFilter.STAR;
import static org.apache.jackrabbit.oak.plugins.observation.filter.GlobbingPathFilter.STAR_STAR;
import java.security.Principal;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -228,6 +231,12 @@ public class ObservationManagerImpl impl
}
Set<String> excludedPaths = getOakPaths(namePathMapper, filter.getExcludedPaths());
PathUtils.unifyInExcludes(includePaths, excludedPaths);
+ if (oakEventFilter != null) {
+ String[] includeGlobPaths = oakEventFilter.getIncludeGlobPaths();
+ if (includeGlobPaths != null) {
+ includePaths.addAll(Arrays.asList(includeGlobPaths));
+ }
+ }
if (includePaths.isEmpty()) {
LOG.warn("The passed filter excludes all events. No event listener registered");
return;
@@ -237,6 +246,20 @@ public class ObservationManagerImpl impl
String depthPattern = isDeep ? STAR + '/' + STAR_STAR : STAR;
List<Condition> includeConditions = newArrayList();
for (String path : includePaths) {
+ final String deepenedPath;
+ if (path.endsWith(STAR)) {
+ // that's the case for a glob ending with * already, so
+ // no need to add another * or **
+ deepenedPath = path;
+ } else if (path.contains(STAR)) {
+ // for any other glob path that doesn't end with *
+ // we only add a single *, not a **
+ deepenedPath = concat (path, STAR);
+ } else {
+ // for any non-glob path we do it the traditional way
+ deepenedPath = concat(path, depthPattern);
+ }
+ includeConditions.add(filterBuilder.path(deepenedPath));
includeConditions.add(filterBuilder.path(concat(path, depthPattern)));
if (oakEventFilter != null && oakEventFilter.getIncludeAncestorsRemove()) {
// with the 'includeAncestorsRemove' extension we need
@@ -245,7 +268,8 @@ public class ObservationManagerImpl impl
// the subtree here as a result.
continue;
}
- filterBuilder.addSubTree(path);
+ // only register the part leading to the first STAR:
+ filterBuilder.addSubTree(pathWithoutGlob(path));
}
List<Condition> excludeConditions = createExclusions(filterBuilder, excludedPaths);
@@ -289,6 +313,23 @@ public class ObservationManagerImpl impl
addEventListener(listener, tracker, filterBuilder.build());
}
+ private String pathWithoutGlob(String path) {
+ if (!path.contains("*")) {
+ return path;
+ }
+ Iterator<String> it = elements(path).iterator();
+ String result = "/";
+ while(it.hasNext()) {
+ String next = it.next();
+ if (next.contains("*")) {
+ // then stop here
+ break;
+ }
+ result = concat(result, next);
+ }
+ return result;
+ }
+
private static List<Condition> createExclusions(FilterBuilder filterBuilder, Iterable<String> excludedPaths) {
List<Condition> conditions = newArrayList();
for (String path : excludedPaths) {
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=1767330&r1=1767329&r2=1767330&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 16:59:32 2016
@@ -75,4 +75,23 @@ public abstract class OakEventFilter ext
* @return this filter with the filter change applied
*/
public abstract OakEventFilter withIncludeSubtreeOnRemove();
+
+ /**
+ * Adds the provided glob paths to the set of include paths.
+ * <p>
+ * The definition of a glob path is
+ * <a href="https://jackrabbit.apache.org/oak/docs/apidocs/org/apache/jackrabbit/oak/plugins/observation/filter/GlobbingPathFilter.html">here</a>
+ * <p>
+ * Note that unlike 'normal' include and exclude paths, this variant
+ * doesn't apply Oak's NamePathMapper.
+ * <p>
+ * This filter property is added in 'or' mode.
+ *
+ * @param globPath
+ * glob path that should be added as include path pattern. Note
+ * that the NamePathMapper is not applied on this globPath.
+ * @return this filter with the filter change applied
+ */
+ public abstract OakEventFilter withIncludeGlobPaths(String... globPaths);
+
}
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=1767330&r1=1767329&r2=1767330&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 16:59:32 2016
@@ -1375,5 +1375,52 @@ public class ObservationTest extends Abs
assertTrue("Unexpected events: " + unexpected, unexpected.isEmpty());
}
+ @Test
+ public void includeGlobPaths() throws Exception {
+
+ Node testNode = getNode(TEST_PATH);
+ testNode.addNode("a1").addNode("b").addNode("c");
+ testNode.addNode("a2").addNode("b").addNode("c");
+ testNode.getSession().save();
+
+ ObservationManagerImpl oManager = (ObservationManagerImpl) observationManager;
+ ExpectationListener listener = new ExpectationListener();
+
+ JackrabbitEventFilter filter = new JackrabbitEventFilter();
+ filter.setEventTypes(ALL_EVENTS);
+ filter = FilterFactory.wrap(filter).withIncludeGlobPaths(TEST_PATH + "/a2/**");
+
+ oManager.addEventListener(listener, filter);
+
+ testNode.getNode("a1").getNode("b").remove();
+ listener.expectRemove(testNode.getNode("a2").getNode("b")).remove();
+ testNode.getSession().save();
+
+ 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());
+
+ Node a3 = testNode.addNode("a3");
+ Node foo = a3.addNode("bar").addNode("foo");
+ testNode.getSession().save();
+
+ filter = new JackrabbitEventFilter();
+ filter.setEventTypes(ALL_EVENTS);
+// filter.setAbsPath(TEST_PATH + "/a3/bar/foo/x");
+ filter = FilterFactory.wrap(filter).withIncludeGlobPaths(TEST_PATH + "/a3/**/x");
+ oManager.addEventListener(listener, filter);
+
+ Node x = foo.addNode("x");
+ listener.expect(x.getPath() + "/jcr:primaryType", PROPERTY_ADDED);
+ testNode.getSession().save();
+
+ Thread.sleep(1000);
+ missing = listener.getMissing(TIME_OUT, TimeUnit.SECONDS);
+ assertTrue("Missing events: " + missing, missing.isEmpty());
+ unexpected = listener.getUnexpected();
+ assertTrue("Unexpected events: " + unexpected, unexpected.isEmpty());
+ }
}