You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2006/10/16 15:55:18 UTC

svn commit: r464496 - in /jackrabbit/trunk/jackrabbit/src: main/java/org/apache/jackrabbit/core/observation/EventFilter.java main/java/org/apache/jackrabbit/core/observation/EventState.java test/java/org/apache/jackrabbit/core/observation/MixinTest.java

Author: mreutegg
Date: Mon Oct 16 06:55:16 2006
New Revision: 464496

URL: http://svn.apache.org/viewvc?view=rev&rev=464496
Log:
JCR-594: It's not possible to register event listeners that filters on mixin supertypes

Modified:
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java
    jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/observation/MixinTest.java

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java?view=diff&rev=464496&r1=464495&r2=464496
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventFilter.java Mon Oct 16 06:55:16 2006
@@ -16,14 +16,15 @@
  */
 package org.apache.jackrabbit.core.observation;
 
+import java.util.Iterator;
+import java.util.Set;
+
 import org.apache.jackrabbit.core.ItemManager;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
 import org.apache.jackrabbit.name.MalformedPathException;
 import org.apache.jackrabbit.name.Path;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.observation.Event;
@@ -34,11 +35,6 @@
  */
 class EventFilter {
 
-    /**
-     * Logger instance for this class.
-     */
-    private static final Logger log = LoggerFactory.getLogger(EventFilter.class);
-
     static final EventFilter BLOCK_ALL = new BlockAllFilter();
 
     /**
@@ -184,11 +180,14 @@
 
         // check node types
         if (nodeTypes != null) {
+            Set eventTypes = eventState.getNodeTypes(session.getNodeTypeManager());
             boolean match = false;
             for (int i = 0; i < nodeTypes.length && !match; i++) {
-                match |= eventState.getNodeType().getQName().equals(nodeTypes[i].getQName())
-                        || eventState.getMixinNames().contains(nodeTypes[i].getQName())
-                        || eventState.getNodeType().isDerivedFrom(nodeTypes[i].getQName());
+                for (Iterator iter = eventTypes.iterator(); iter.hasNext();) {
+                    NodeTypeImpl nodeType = (NodeTypeImpl) iter.next();
+                    match |= nodeType.getQName().equals(nodeTypes[i].getQName())
+                            || nodeType.isDerivedFrom(nodeTypes[i].getQName());
+                }
             }
             if (!match) {
                 return true;
@@ -202,7 +201,7 @@
             // Event.getPath().
             // for property events, the relevant path is the path of the
             // node where the property belongs to.
-            Path eventPath = null;
+            Path eventPath;
             if (type == Event.NODE_ADDED || type == Event.NODE_REMOVED) {
                 Path.PathElement nameElem = eventState.getChildRelPath();
                 if (nameElem.getIndex() == 0) {

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java?view=diff&rev=464496&r1=464495&r2=464496
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java Mon Oct 16 06:55:16 2006
@@ -17,14 +17,22 @@
 package org.apache.jackrabbit.core.observation;
 
 import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
 import org.apache.jackrabbit.core.ItemId;
 import org.apache.jackrabbit.core.PropertyId;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.name.Path;
+import org.apache.jackrabbit.name.QName;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
 
 import javax.jcr.Session;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
 import javax.jcr.observation.Event;
 import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Collections;
 
 /**
  * The <code>EventState</code> class encapsulates the session
@@ -33,6 +41,11 @@
 public class EventState {
 
     /**
+     * The logger instance for this class.
+     */
+    private static final Logger log = LoggerFactory.getLogger(EventState.class);
+
+    /**
      * The {@link javax.jcr.observation.Event} of this event.
      */
     private final int type;
@@ -71,6 +84,15 @@
     private final Set mixins;
 
     /**
+     * Set of node types. This Set consists of the primary node type and all
+     * mixin types assigned to the associated parent node of this event state.
+     * </p>
+     * This <code>Set</code> is initialized when
+     * {@link #getNodeTypes(NodeTypeManagerImpl)} is called for the first time.
+     */
+    private Set allTypes;
+
+    /**
      * The session that caused this event.
      */
     private final Session session;
@@ -349,6 +371,31 @@
      */
     public Set getMixinNames() {
         return mixins;
+    }
+
+    /**
+     * Returns the <code>Set</code> of {@link javax.jcr.nodetype.NodeType}s
+     * assigned to the parent node associated with this event. This
+     * <code>Set</code> includes the primary type as well as all the mixin types
+     * assigned to the parent node.
+     *
+     * @return <code>Set</code> of {@link javax.jcr.nodetype.NodeType}s.
+     */
+    public Set getNodeTypes(NodeTypeManagerImpl ntMgr) {
+        if (allTypes == null) {
+            Set tmp = new HashSet();
+            tmp.add(nodeType);
+            for (Iterator it = mixins.iterator(); it.hasNext(); ) {
+                QName mixinName = (QName) it.next();
+                try {
+                    tmp.add(ntMgr.getNodeType(mixinName));
+                } catch (NoSuchNodeTypeException e) {
+                    log.warn("Unknown node type: " + mixinName);
+                }
+            }
+            allTypes = Collections.unmodifiableSet(tmp);
+        }
+        return allTypes;
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/observation/MixinTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/observation/MixinTest.java?view=diff&rev=464496&r1=464495&r2=464496
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/observation/MixinTest.java (original)
+++ jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/observation/MixinTest.java Mon Oct 16 06:55:16 2006
@@ -104,6 +104,29 @@
     }
 
     /**
+     * Checks if an event listener registered for a mixin type T also gets
+     * notifications for an event on a node with a mixin type which is derived
+     * from T.
+     */ 
+    public void testDerivedMixin() throws RepositoryException {
+        Node node1 = testRootNode.addNode(nodeName1, testNodeType);
+        node1.addMixin(mixVersionable);
+
+        testRootNode.save();
+
+        EventResult propertyAddedListener = new EventResult(log);
+        // mix:versionable is derived from mix:referenceable
+        addEventListener(propertyAddedListener, new String[]{mixReferenceable}, Event.PROPERTY_ADDED);
+
+        node1.setProperty(propertyName1, "test");
+        testRootNode.save();
+
+        removeEventListener(propertyAddedListener);
+        Event[] added = propertyAddedListener.getEvents(DEFAULT_WAIT_TIMEOUT);
+        checkPropertyAdded(added, new String[]{nodeName1 + "/" + propertyName1});
+    }
+
+    /**
      * Registers an <code>EventListener</code> for events of the specified
      * type(s).
      *