jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mreut...@apache.org
Subject svn commit: r239609 - in /incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core: observation/ state/
Date Wed, 24 Aug 2005 11:36:32 GMT
Author: mreutegg
Date: Wed Aug 24 04:36:26 2005
New Revision: 239609

URL: http://svn.apache.org/viewcvs?rev=239609&view=rev
Log:
Move preparation of events out of write lock to prevent possible deadlock situations.

Modified:
    incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventConsumer.java
    incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventState.java
    incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java
    incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/FilteredEventIterator.java
    incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java
    incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java

Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventConsumer.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventConsumer.java?rev=239609&r1=239608&r2=239609&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventConsumer.java
(original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventConsumer.java
Wed Aug 24 04:36:26 2005
@@ -20,6 +20,7 @@
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.PropertyId;
 import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.state.ItemState;
 import org.apache.jackrabbit.core.security.AccessManager;
 import org.apache.log4j.Logger;
 
@@ -29,11 +30,11 @@
 import javax.jcr.observation.EventIterator;
 import javax.jcr.observation.EventListener;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.WeakHashMap;
 
 /**
  * The <code>EventConsumer</code> class combines the {@link
@@ -66,11 +67,11 @@
     private final EventFilter filter;
 
     /**
-     * A map of <code>Set</code> objects that hold references to denied
-     * <code>EventState</code>s. The map uses the <code>EventStateCollection</code>
-     * as the key to reference a deny Set.
+     * A map of <code>Set</code> objects that hold references to
+     * <code>ItemId</code>s of denied <code>ItemState</code>s. The
map uses the
+     * <code>EventStateCollection</code> as the key to reference a deny Set.
      */
-    private final Map accessDenied = Collections.synchronizedMap(new HashMap());
+    private final Map accessDenied = Collections.synchronizedMap(new WeakHashMap());
 
     /**
      * cached hash code value
@@ -165,7 +166,7 @@
                     if (denied == null) {
                         denied = new HashSet();
                     }
-                    denied.add(state);
+                    denied.add(state.getId());
                 }
             }
         }
@@ -175,12 +176,43 @@
     }
 
     /**
+     * Checks for which deleted <code>ItemStates</code> this
+     * <code>EventConsumer</code> has enough access rights to see the event.
+     *
+     * @param events       the collection of {@link EventState}s.
+     * @param deletedItems Iterator of deleted <code>ItemState</code>s.
+     */
+    void prepareDeleted(EventStateCollection events, Iterator deletedItems) {
+        Set denied = null;
+        while (deletedItems.hasNext()) {
+            ItemState item = (ItemState) deletedItems.next();
+            // check read permission
+            boolean granted = false;
+            try {
+                granted = session.getAccessManager().isGranted(item.getId(), AccessManager.READ);
+            } catch (RepositoryException e) {
+                log.warn("Unable to check access rights for item: " + item.getId());
+            }
+            if (!granted) {
+                if (denied == null) {
+                    denied = new HashSet();
+                }
+                denied.add(item.getId());
+            }
+        }
+        if (denied != null) {
+            accessDenied.put(events, denied);
+        }
+    }
+
+    /**
      * Dispatches the events to the <code>EventListener</code>.
      *
      * @param events a collection of {@link EventState}s
      *               to dispatch.
      */
     void consumeEvents(EventStateCollection events) throws RepositoryException {
+        // Set of ItemIds of denied ItemStates
         Set denied = (Set) accessDenied.remove(events);
         // check permissions
         for (Iterator it = events.iterator(); it.hasNext();) {
@@ -200,7 +232,7 @@
                     if (denied == null) {
                         denied = new HashSet();
                     }
-                    denied.add(state);
+                    denied.add(state.getId());
                 }
             }
         }

Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventState.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventState.java?rev=239609&r1=239608&r2=239609&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventState.java
(original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventState.java
Wed Aug 24 04:36:26 2005
@@ -17,6 +17,9 @@
 package org.apache.jackrabbit.core.observation;
 
 import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+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 javax.jcr.Session;
@@ -331,6 +334,21 @@
      */
     Session getSession() {
         return session;
+    }
+
+    /**
+     * Returns the id of the associated item of this <code>EventState</code>.
+     *
+     * @return the <code>ItemId</code>.
+     */
+    ItemId getId() {
+        if (childUUID == null) {
+            // property event
+            return new PropertyId(parentUUID, childRelPath.getName());
+        } else {
+            // node event
+            return new NodeId(childUUID);
+        }
     }
 
     /**

Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java?rev=239609&r1=239608&r2=239609&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java
(original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/EventStateCollection.java
Wed Aug 24 04:36:26 2005
@@ -45,6 +45,16 @@
  * The <code>EventStateCollection</code> class implements how {@link EventState}
  * objects are created based on the {@link org.apache.jackrabbit.core.state.ItemState}s
  * passed to the {@link #createEventStates} method.
+ * <p/>
+ * The basic sequence of method calls is:
+ * <ul>
+ * <li>{@link #createEventStates} or {@link #addAll} to create or add event
+ * states to the collection</li>
+ * <li>{@link #prepare} or {@link #prepareDeleted} to prepare the events. If
+ * this step is omitted, EventListeners might see events of deleted item
+ * they are not allowed to see.</li>
+ * <li>{@link #dispatch()} to dispatch the events to the EventListeners.</li>
+ * </ul>
  */
 public final class EventStateCollection {
 
@@ -343,10 +353,19 @@
     }
 
     /**
-     * Prepares the events for dispatching.
+     * Prepares already added events for dispatching.
      */
     public void prepare() {
         dispatcher.prepareEvents(this);
+    }
+
+    /**
+     * Prepares deleted items from <code>changes</code>.
+     *
+     * @param changes the changes to prepare.
+     */
+    public void prepareDeleted(ChangeLog changes) {
+        dispatcher.prepareDeleted(this, changes);
     }
 
     /**

Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/FilteredEventIterator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/FilteredEventIterator.java?rev=239609&r1=239608&r2=239609&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/FilteredEventIterator.java
(original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/FilteredEventIterator.java
Wed Aug 24 04:36:26 2005
@@ -45,6 +45,9 @@
      */
     private final EventFilter filter;
 
+    /**
+     * Set of <code>ItemId</code>s of denied <code>ItemState</code>s.
+     */
     private final Set denied;
 
     /**
@@ -63,9 +66,9 @@
      * @param c      an unmodifiable Collection of {@link javax.jcr.observation.Event}s.
      * @param filter only event that pass the filter will be dispatched to the
      *               event listener.
-     * @param denied <code>Set</code> of denied <code>EventState</code>s
+     * @param denied <code>Set</code> of <code>ItemId</code>s of
denied <code>ItemState</code>s
      *               rejected by the <code>AccessManager</code>. If
-     *               <code>null</code> no <code>EventState</code>
is denied.
+     *               <code>null</code> no <code>ItemState</code>
is denied.
      */
     public FilteredEventIterator(EventStateCollection c,
                                  EventFilter filter,
@@ -151,11 +154,9 @@
         while (next == null && actualEvents.hasNext()) {
             state = (EventState) actualEvents.next();
             // check denied set
-            if (denied == null || !denied.contains(state)) {
+            if (denied == null || !denied.contains(state.getId())) {
                 try {
-                    next = filter.blocks(state) ? null : new EventImpl(filter.getSession(),
-                            /* filter.getItemManager(), */
-                            state);
+                    next = filter.blocks(state) ? null : new EventImpl(filter.getSession(),
state);
                 } catch (RepositoryException e) {
                     log.error("Exception while applying filter.", e);
                 }

Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java?rev=239609&r1=239608&r2=239609&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java
(original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/observation/ObservationManagerFactory.java
Wed Aug 24 04:36:26 2005
@@ -21,6 +21,7 @@
 import org.apache.commons.collections.buffer.UnboundedFifoBuffer;
 import org.apache.jackrabbit.core.ItemManager;
 import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.state.ChangeLog;
 import org.apache.log4j.Logger;
 
 import java.util.Collections;
@@ -182,6 +183,22 @@
         for (Iterator it = consumers.iterator(); it.hasNext();) {
             EventConsumer c = (EventConsumer) it.next();
             c.prepareEvents(events);
+        }
+    }
+
+    /**
+     * Prepares changes that involve deleted item states.
+     *
+     * @param events the event state collection.
+     * @param changes the changes.
+     */
+    void prepareDeleted(EventStateCollection events, ChangeLog changes) {
+        Set consumers = new HashSet();
+        consumers.addAll(getSynchronousConsumers());
+        consumers.addAll(getAsynchronousConsumers());
+        for (Iterator it = consumers.iterator(); it.hasNext();) {
+            EventConsumer c = (EventConsumer) it.next();
+            c.prepareDeleted(events, changes.deletedStates());
         }
     }
 

Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=239609&r1=239608&r2=239609&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
(original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
Wed Aug 24 04:36:26 2005
@@ -333,6 +333,12 @@
         // todo: remember by provider
         ArrayList virtualRefs = new ArrayList();
 
+        EventStateCollection events = null;
+        if (obsMgr != null) {
+            events = obsMgr.createEventStateCollection();
+            events.prepareDeleted(local);
+        }
+
         acquireWriteLock();
         boolean holdingWriteLock = true;
 
@@ -366,7 +372,6 @@
                 }
             }
 
-            EventStateCollection events = null;
             boolean succeeded = false;
 
             try {
@@ -404,11 +409,9 @@
                     shared.added(state.getOverlayedState());
                 }
 
-                /* prepare the events */
-                if (obsMgr != null) {
-                    events = obsMgr.createEventStateCollection();
+                /* create event states */
+                if (events != null) {
                     events.createEventStates(root.getUUID(), local, this);
-                    events.prepare();
                 }
 
                 /* Push all changes from the local items to the shared items */



Mime
View raw message