jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r1577244 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/observation/ test/java/org/apache/jackrabbit/api/
Date Thu, 13 Mar 2014 16:55:21 GMT
Author: mduerig
Date: Thu Mar 13 16:55:21 2014
New Revision: 1577244

URL: http://svn.apache.org/r1577244
Log:
JCR-3747: Implement JackrabbitObservationManager
Initial implementation

Added:
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/JackrabbitObservationManagerTest.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/TestAll.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java?rev=1577244&r1=1577243&r2=1577244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java
Thu Mar 13 16:55:21 2014
@@ -16,17 +16,19 @@
  */
 package org.apache.jackrabbit.core.observation;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.observation.Event;
+
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
 import org.apache.jackrabbit.spi.Path;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.observation.Event;
-
 /**
  * The <code>EventFilter</code> class implements the filter logic based
  * on the session's access rights and the specified filter rules.
@@ -47,9 +49,9 @@ public class EventFilter {
     private final long eventTypes;
 
     /**
-     * Only allow Items with the specified <code>path</code>
+     * Only allow Items with the specified <code>paths</code>
      */
-    private final Path path;
+    private final List<Path> paths;
 
     /**
      * If <code>isDeep</code> is <code>true</code> also Items under
<code>absPath</code>
@@ -74,13 +76,19 @@ public class EventFilter {
     private final boolean noLocal;
 
     /**
+     * If <code>noExternal</code> is true this filter will block events from
+     * other cluster nodes.
+     */
+    private final boolean noExternal;
+
+    /**
      * Creates a new <code>EventFilter</code> instance.
      *
      * @param session    the <code>Session</code> that registered the {@link
      *                   javax.jcr.observation.EventListener}.
      * @param eventTypes only allow specified {@link javax.jcr.observation.Event} types.
-     * @param path       only allow {@link javax.jcr.Item} with
-     *                   <code>path</code>.
+     * @param paths      only allow {@link javax.jcr.Item} with a path in
+     *                   <code>paths</code>.
      * @param isDeep     if <code>true</code> also allow events for {@link
      *                   javax.jcr.Item}s below <code>absPath</code>.
      * @param ids        only allow events for {@link javax.jcr.Node}s with
@@ -95,17 +103,19 @@ public class EventFilter {
      */
     EventFilter(SessionImpl session,
                 long eventTypes,
-                Path path,
+                List<Path> paths,
                 boolean isDeep,
                 NodeId[] ids,
                 NodeTypeImpl[] nodeTypes,
-                boolean noLocal) {
+                boolean noLocal,
+                boolean noExternal) {
         this.session = session;
         this.eventTypes = eventTypes;
-        this.path = path;
+        this.paths = paths;
         this.isDeep = isDeep;
         this.ids = ids;
         this.noLocal = noLocal;
+        this.noExternal = noExternal;
         this.nodeTypes = nodeTypes;
     }
 
@@ -133,6 +143,10 @@ public class EventFilter {
             return true;
         }
 
+        if (noExternal && eventState.isExternal()) {
+            return true;
+        }
+
         // UUIDs, types, and paths do not need to match for persist
         if (eventState.getType() == Event.PERSIST) {
             return false;
@@ -166,11 +180,14 @@ public class EventFilter {
             }
         }
 
-        // finally check path
+        // finally check paths
         Path eventPath = eventState.getParentPath();
-        boolean match = eventPath.equals(path);
-        if (!match && isDeep) {
-            match = eventPath.isDescendantOf(path);
+        boolean match = false;
+        for (Path path : paths) {
+            if (eventPath.equals(path) || isDeep && eventPath.isDescendantOf(path))
{
+                match = true;
+                break;
+            }
         }
 
         return !match;
@@ -186,7 +203,7 @@ public class EventFilter {
          * Creates a new <code>BlockAllFilter</code>.
          */
         BlockAllFilter() {
-            super(null, 0, null, true, null, null, true);
+            super(null, 0, Collections.<Path>emptyList(), true, null, null, true, true);
         }
 
         /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java?rev=1577244&r1=1577243&r2=1577244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/ObservationManagerImpl.java
Thu Mar 13 16:55:21 2014
@@ -16,15 +16,10 @@
  */
 package org.apache.jackrabbit.core.observation;
 
-import org.apache.jackrabbit.core.SessionImpl;
-import org.apache.jackrabbit.core.id.NodeId;
-import org.apache.jackrabbit.core.cluster.ClusterNode;
-import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
-import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
-import org.apache.jackrabbit.spi.commons.conversion.NameException;
-import org.apache.jackrabbit.spi.Path;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 import javax.jcr.AccessDeniedException;
 import javax.jcr.RepositoryException;
@@ -34,12 +29,25 @@ import javax.jcr.observation.EventListen
 import javax.jcr.observation.EventListenerIterator;
 import javax.jcr.observation.ObservationManager;
 
+import org.apache.jackrabbit.api.observation.JackrabbitEventFilter;
+import org.apache.jackrabbit.api.observation.JackrabbitObservationManager;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.cluster.ClusterNode;
+import org.apache.jackrabbit.core.id.NodeId;
+import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.commons.conversion.NameException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * Each <code>Session</code> instance has its own <code>ObservationManager</code>
  * instance. The class <code>SessionLocalObservationManager</code> implements
  * this behaviour.
  */
-public class ObservationManagerImpl implements ObservationManager, EventStateCollectionFactory
{
+public class ObservationManagerImpl implements EventStateCollectionFactory,
+        JackrabbitObservationManager {
 
     /**
      * The logger instance of this class
@@ -110,12 +118,28 @@ public class ObservationManagerImpl impl
             throws RepositoryException {
 
         // create filter
-        EventFilter filter = createEventFilter(eventTypes, absPath,
-                isDeep, uuid, nodeTypeName, noLocal);
+        EventFilter filter = createEventFilter(eventTypes, Collections.singletonList(absPath),
+                isDeep, uuid, nodeTypeName, noLocal, false);
 
         dispatcher.addConsumer(new EventConsumer(session, listener, filter));
     }
 
+    @Override
+    public void addEventListener(EventListener listener, JackrabbitEventFilter filter)
+            throws RepositoryException {
+
+        List<String> absPaths = new ArrayList<String>(Arrays.asList(filter.getAdditionalPaths()));
+        if (filter.getAbsPath() != null) {
+            absPaths.add(filter.getAbsPath());
+        }
+
+        EventFilter f = createEventFilter(filter.getEventTypes(), absPaths,
+                filter.getIsDeep(), filter.getIdentifiers(), filter.getNodeTypes(),
+                filter.getNoLocal(), filter.getNoExternal());
+
+        dispatcher.addConsumer(new EventConsumer(session, listener, f));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -172,20 +196,22 @@ public class ObservationManagerImpl impl
      * Creates a new event filter with the given restrictions.
      *
      * @param eventTypes A combination of one or more event type constants encoded as a bitmask.
-     * @param absPath an absolute path.
+     * @param absPaths absolute paths.
      * @param isDeep a <code>boolean</code>.
      * @param uuid array of UUIDs.
      * @param nodeTypeName array of node type names.
      * @param noLocal a <code>boolean</code>.
+     * @param noExternal a <code>boolean</code>.
      * @return the event filter with the given restrictions.
      * @throws RepositoryException if an error occurs.
      */
     public EventFilter createEventFilter(int eventTypes,
-                                         String absPath,
+                                         List<String> absPaths,
                                          boolean isDeep,
                                          String[] uuid,
                                          String[] nodeTypeName,
-                                         boolean noLocal)
+                                         boolean noLocal,
+                                         boolean noExternal)
             throws RepositoryException {
         // create NodeType instances from names
         NodeTypeImpl[] nodeTypes;
@@ -199,17 +225,20 @@ public class ObservationManagerImpl impl
             }
         }
 
-        Path path;
-        try {
-            path = session.getQPath(absPath).getNormalizedPath();
-        } catch (NameException e) {
-            String msg = "invalid path syntax: " + absPath;
-            log.debug(msg);
-            throw new RepositoryException(msg, e);
-        }
-        if (!path.isAbsolute()) {
-            throw new RepositoryException("absPath must be absolute");
-        }
+        List<Path> paths = new ArrayList<Path>();
+        for (String absPath : absPaths) {
+            try {
+                Path normalizedPath = session.getQPath(absPath).getNormalizedPath();
+                if (!normalizedPath.isAbsolute()) {
+                    throw new RepositoryException("absPath must be absolute");
+                }
+                paths.add(normalizedPath);
+            } catch (NameException e) {
+                String msg = "invalid path syntax: " + absPath;
+                log.debug(msg);
+                throw new RepositoryException(msg, e);
+
+        }            }
         NodeId[] ids = null;
         if (uuid != null) {
             ids = new NodeId[uuid.length];
@@ -219,7 +248,7 @@ public class ObservationManagerImpl impl
         }
         // create filter
         return new EventFilter(
-                session, eventTypes, path, isDeep, ids, nodeTypes, noLocal);
+                session, eventTypes, paths, isDeep, ids, nodeTypes, noLocal, noExternal);
     }
 
     /**
@@ -251,7 +280,7 @@ public class ObservationManagerImpl impl
         }
 
         EventFilter filter = createEventFilter(
-                eventTypes, absPath, isDeep, uuid, nodeTypeName, false);
+                eventTypes, Collections.singletonList(absPath), isDeep, uuid, nodeTypeName,
false, false);
         return new EventJournalImpl(
                 filter, clusterNode.getJournal(), clusterNode.getId(), session);
     }

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/JackrabbitObservationManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/JackrabbitObservationManagerTest.java?rev=1577244&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/JackrabbitObservationManagerTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/JackrabbitObservationManagerTest.java
Thu Mar 13 16:55:21 2014
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.api;
+
+import static javax.jcr.observation.Event.NODE_ADDED;
+
+import java.util.concurrent.ExecutionException;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.observation.Event;
+
+import org.apache.jackrabbit.api.observation.JackrabbitEventFilter;
+import org.apache.jackrabbit.api.observation.JackrabbitObservationManager;
+import org.apache.jackrabbit.test.api.observation.AbstractObservationTest;
+import org.apache.jackrabbit.test.api.observation.EventResult;
+
+public class JackrabbitObservationManagerTest extends AbstractObservationTest {
+
+    public void testImplementsJackrabbitObservationManager() throws RepositoryException {
+        assertTrue(obsMgr instanceof JackrabbitObservationManager);
+    }
+
+    public void testDisjunctPaths() throws ExecutionException, InterruptedException, RepositoryException
{
+        JackrabbitObservationManager oManager = (JackrabbitObservationManager) obsMgr;
+        EventResult listener = new EventResult(log);
+        JackrabbitEventFilter filter = new JackrabbitEventFilter()
+                .setAdditionalPaths('/' + testPath + "/a", '/' + testPath + "/x")
+                .setEventTypes(NODE_ADDED);
+        oManager.addEventListener(listener, filter);
+        try {
+            Node b = testRootNode.addNode("a").addNode("b");
+            b.addNode("c");
+            Node y = testRootNode.addNode("x").addNode("y");
+            y.addNode("z");
+            testRootNode.getSession().save();
+
+            Event[] added = listener.getEvents(DEFAULT_WAIT_TIMEOUT);
+            checkNodeAdded(added, new String[] {"a/b", "x/y"}, null);
+        } finally {
+            oManager.removeEventListener(listener);
+        }
+    }
+
+}

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/TestAll.java?rev=1577244&r1=1577243&r2=1577244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/TestAll.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/TestAll.java
Thu Mar 13 16:55:21 2014
@@ -36,6 +36,7 @@ public class TestAll extends AbstractJCR
         TestSuite suite = new TestSuite("api tests");
 
         suite.addTestSuite(JackrabbitNodeTest.class);
+        suite.addTestSuite(JackrabbitObservationManagerTest.class);
 
         return suite;
     }



Mime
View raw message