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

svn commit: r821598 - in /jackrabbit/trunk/jackrabbit-jcr2spi/src: main/java/org/apache/jackrabbit/jcr2spi/ main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ test/java/org/apache/jackrabbit/jcr2spi/ test/java/org/apache/jackrabbit/jcr2spi/observation/

Author: mduerig
Date: Sun Oct  4 20:16:18 2009
New Revision: 821598

URL: http://svn.apache.org/viewvc?rev=821598&view=rev
Log:
JCR-2293: PathNotFoundException but item exists

Added:
    jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/observation/
    jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/observation/ObservationTest.java   (with props)
Modified:
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/TestAll.java

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java?rev=821598&r1=821597&r2=821598&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java Sun Oct  4 20:16:18 2009
@@ -16,107 +16,106 @@
  */
 package org.apache.jackrabbit.jcr2spi;
 
-import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistryImpl;
-import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.MergeException;
+import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.query.InvalidQueryException;
+import javax.jcr.version.VersionException;
+
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEventListener;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManagerImpl;
+import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeTypeProvider;
 import org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider;
 import org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProviderImpl;
-import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeTypeProvider;
 import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeCache;
-import org.apache.jackrabbit.jcr2spi.state.ItemState;
-import org.apache.jackrabbit.jcr2spi.state.ChangeLog;
-import org.apache.jackrabbit.jcr2spi.state.UpdatableItemStateManager;
-import org.apache.jackrabbit.jcr2spi.state.ItemStateFactory;
-import org.apache.jackrabbit.jcr2spi.state.WorkspaceItemStateFactory;
-import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.state.TransientItemStateFactory;
-import org.apache.jackrabbit.jcr2spi.state.TransientISFactory;
-import org.apache.jackrabbit.jcr2spi.state.Status;
-import org.apache.jackrabbit.jcr2spi.operation.OperationVisitor;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistryImpl;
+import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
+import org.apache.jackrabbit.jcr2spi.operation.AddLabel;
 import org.apache.jackrabbit.jcr2spi.operation.AddNode;
 import org.apache.jackrabbit.jcr2spi.operation.AddProperty;
+import org.apache.jackrabbit.jcr2spi.operation.Checkin;
+import org.apache.jackrabbit.jcr2spi.operation.Checkout;
+import org.apache.jackrabbit.jcr2spi.operation.Checkpoint;
 import org.apache.jackrabbit.jcr2spi.operation.Clone;
 import org.apache.jackrabbit.jcr2spi.operation.Copy;
-import org.apache.jackrabbit.jcr2spi.operation.Move;
-import org.apache.jackrabbit.jcr2spi.operation.Remove;
-import org.apache.jackrabbit.jcr2spi.operation.SetMixin;
-import org.apache.jackrabbit.jcr2spi.operation.SetPropertyValue;
-import org.apache.jackrabbit.jcr2spi.operation.ReorderNodes;
-import org.apache.jackrabbit.jcr2spi.operation.Operation;
-import org.apache.jackrabbit.jcr2spi.operation.Checkout;
-import org.apache.jackrabbit.jcr2spi.operation.Checkin;
-import org.apache.jackrabbit.jcr2spi.operation.Update;
-import org.apache.jackrabbit.jcr2spi.operation.Restore;
-import org.apache.jackrabbit.jcr2spi.operation.ResolveMergeConflict;
-import org.apache.jackrabbit.jcr2spi.operation.Merge;
+import org.apache.jackrabbit.jcr2spi.operation.CreateActivity;
+import org.apache.jackrabbit.jcr2spi.operation.CreateConfiguration;
 import org.apache.jackrabbit.jcr2spi.operation.LockOperation;
 import org.apache.jackrabbit.jcr2spi.operation.LockRefresh;
 import org.apache.jackrabbit.jcr2spi.operation.LockRelease;
-import org.apache.jackrabbit.jcr2spi.operation.AddLabel;
+import org.apache.jackrabbit.jcr2spi.operation.Merge;
+import org.apache.jackrabbit.jcr2spi.operation.Move;
+import org.apache.jackrabbit.jcr2spi.operation.Operation;
+import org.apache.jackrabbit.jcr2spi.operation.OperationVisitor;
+import org.apache.jackrabbit.jcr2spi.operation.Remove;
+import org.apache.jackrabbit.jcr2spi.operation.RemoveActivity;
 import org.apache.jackrabbit.jcr2spi.operation.RemoveLabel;
 import org.apache.jackrabbit.jcr2spi.operation.RemoveVersion;
-import org.apache.jackrabbit.jcr2spi.operation.WorkspaceImport;
-import org.apache.jackrabbit.jcr2spi.operation.Checkpoint;
-import org.apache.jackrabbit.jcr2spi.operation.CreateActivity;
-import org.apache.jackrabbit.jcr2spi.operation.CreateConfiguration;
-import org.apache.jackrabbit.jcr2spi.operation.RemoveActivity;
+import org.apache.jackrabbit.jcr2spi.operation.ReorderNodes;
+import org.apache.jackrabbit.jcr2spi.operation.ResolveMergeConflict;
+import org.apache.jackrabbit.jcr2spi.operation.Restore;
+import org.apache.jackrabbit.jcr2spi.operation.SetMixin;
 import org.apache.jackrabbit.jcr2spi.operation.SetPrimaryType;
+import org.apache.jackrabbit.jcr2spi.operation.SetPropertyValue;
+import org.apache.jackrabbit.jcr2spi.operation.Update;
+import org.apache.jackrabbit.jcr2spi.operation.WorkspaceImport;
 import org.apache.jackrabbit.jcr2spi.security.AccessManager;
-import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
-import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
-import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEventListener;
-import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
-import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManagerImpl;
-import org.apache.jackrabbit.spi.Path;
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.RepositoryService;
-import org.apache.jackrabbit.spi.SessionInfo;
-import org.apache.jackrabbit.spi.NodeId;
-import org.apache.jackrabbit.spi.IdFactory;
-import org.apache.jackrabbit.spi.LockInfo;
-import org.apache.jackrabbit.spi.QueryInfo;
-import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.PropertyId;
+import org.apache.jackrabbit.jcr2spi.state.ChangeLog;
+import org.apache.jackrabbit.jcr2spi.state.ItemState;
+import org.apache.jackrabbit.jcr2spi.state.ItemStateFactory;
+import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.state.Status;
+import org.apache.jackrabbit.jcr2spi.state.TransientISFactory;
+import org.apache.jackrabbit.jcr2spi.state.TransientItemStateFactory;
+import org.apache.jackrabbit.jcr2spi.state.UpdatableItemStateManager;
+import org.apache.jackrabbit.jcr2spi.state.WorkspaceItemStateFactory;
 import org.apache.jackrabbit.spi.Batch;
+import org.apache.jackrabbit.spi.Event;
 import org.apache.jackrabbit.spi.EventBundle;
 import org.apache.jackrabbit.spi.EventFilter;
-import org.apache.jackrabbit.spi.QNodeTypeDefinition;
-import org.apache.jackrabbit.spi.QValue;
-import org.apache.jackrabbit.spi.Event;
+import org.apache.jackrabbit.spi.IdFactory;
+import org.apache.jackrabbit.spi.ItemId;
+import org.apache.jackrabbit.spi.LockInfo;
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.NameFactory;
+import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.PathFactory;
+import org.apache.jackrabbit.spi.PropertyId;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.QueryInfo;
+import org.apache.jackrabbit.spi.RepositoryService;
+import org.apache.jackrabbit.spi.SessionInfo;
 import org.apache.jackrabbit.spi.Subscription;
 import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeStorage;
-import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.NamespaceRegistry;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.AccessDeniedException;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.NamespaceException;
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.ItemExistsException;
-import javax.jcr.InvalidItemStateException;
-import javax.jcr.MergeException;
-import javax.jcr.ReferentialIntegrityException;
-import javax.jcr.query.InvalidQueryException;
-import javax.jcr.version.VersionException;
-import javax.jcr.lock.LockException;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
-import javax.jcr.nodetype.ConstraintViolationException;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Collection;
-
-import EDU.oswego.cs.dl.util.concurrent.Sync;
 import EDU.oswego.cs.dl.util.concurrent.Mutex;
+import EDU.oswego.cs.dl.util.concurrent.Sync;
 
 /**
  * <code>WorkspaceManager</code>...
@@ -162,7 +161,7 @@
      * List of event listener that are set on this WorkspaceManager to get
      * notifications about local and external changes.
      */
-    private final Set<InternalEventListener> listeners = new HashSet<InternalEventListener>();
+    private final List<InternalEventListener> listeners = new LinkedList<InternalEventListener>();
 
     /**
      * The current subscription for change events if there are listeners.
@@ -173,6 +172,7 @@
                             CacheBehaviour cacheBehaviour, int pollTimeout,
                             boolean enableObservation)
         throws RepositoryException {
+
         this.service = service;
         this.sessionInfo = sessionInfo;
         this.cacheBehaviour = cacheBehaviour;
@@ -188,7 +188,19 @@
         TransientItemStateFactory stateFactory = createItemStateFactory();
         this.isf = stateFactory;
         this.hierarchyManager = createHierarchyManager(stateFactory, idFactory);
-        createHierarchyListener(hierarchyManager);
+
+        // If cache behavior is observation register a hierarchy listener which is
+        // notified about all changes. Otherwise just add a hierarchy listener which
+        // is only notified on changes for which client event listeners have been
+        // installed. Note: this listener has to be the first one called in order
+        // for the hierarchy to be consistent with the event (See JCR-2293).
+        InternalEventListener listener = createHierarchyListener(hierarchyManager);
+        if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
+            addEventListener(listener);
+        }
+        else {
+            listeners.add(listener);
+        }
     }
 
     public NamespaceRegistryImpl getNamespaceRegistryImpl() {
@@ -241,7 +253,7 @@
      * @return lock tokens present with the <code>SessionInfo</code>.
      * @throws UnsupportedRepositoryOperationException
      * @throws RepositoryException
-     * @see org.apache.jackrabbit.spi.SessionInfo#getLockTokens() 
+     * @see org.apache.jackrabbit.spi.SessionInfo#getLockTokens()
      */
     public String[] getLockTokens() throws UnsupportedRepositoryOperationException, RepositoryException {
         return sessionInfo.getLockTokens();
@@ -339,12 +351,12 @@
         synchronized (listeners) {
             listeners.add(listener);
             EventFilter[] filters = getEventFilters(listeners);
-            if (listeners.size() == 1) {
+            if (subscription == null) {
                 subscription = service.createSubscription(sessionInfo, filters);
             } else {
                 service.updateEventFilters(subscription, filters);
             }
-            listeners.notify();
+            listeners.notifyAll();
         }
     }
 
@@ -532,7 +544,7 @@
 
     /**
      * Deletes the workspace with the specified <code>name</code>.
-     * 
+     *
      * @param name
      * @throws RepositoryException
      */
@@ -1145,7 +1157,7 @@
                     InternalEventListener[] iel;
                     Subscription subscr;
                     synchronized (listeners) {
-                        while (listeners.isEmpty()) {
+                        while (subscription == null) {
                             listeners.wait();
                         }
                         iel = listeners.toArray(new InternalEventListener[0]);
@@ -1184,4 +1196,5 @@
             }
         }
     }
+
 }

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java?rev=821598&r1=821597&r2=821598&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java Sun Oct  4 20:16:18 2009
@@ -16,26 +16,27 @@
  */
 package org.apache.jackrabbit.jcr2spi.hierarchy;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+
 import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
 import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
-import org.apache.jackrabbit.spi.EventFilter;
+import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
 import org.apache.jackrabbit.spi.Event;
 import org.apache.jackrabbit.spi.EventBundle;
+import org.apache.jackrabbit.spi.EventFilter;
+import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.Path;
-import org.apache.jackrabbit.spi.ItemId;
-
-import javax.jcr.RepositoryException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.List;
-import java.util.ArrayList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * <code>HierarchyEventListener</code>...
@@ -59,17 +60,13 @@
                 filter = wspManager.createEventFilter(Event.ALL_TYPES, root, true, null, null, true);
             } catch (RepositoryException e) {
                 // spi does not support observation, or another error occurred.
+                log.debug("Creating event filter for cache behavoir observation failed", e);
             }
             if (filter == null) {
                 this.eventFilter = Collections.emptyList();
             } else {
                 this.eventFilter = Collections.singletonList(filter);
             }
-            try {
-                wspManager.addEventListener(this);
-            } catch (RepositoryException e) {
-                // spi does not support observation, or another error occurred.
-            }
         } else {
             this.eventFilter = Collections.emptyList();
         }

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/TestAll.java?rev=821598&r1=821597&r2=821598&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/TestAll.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/TestAll.java Sun Oct  4 20:16:18 2009
@@ -20,6 +20,7 @@
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
+import org.apache.jackrabbit.jcr2spi.observation.ObservationTest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -102,6 +103,9 @@
         // repository
         suite.addTestSuite(LoginTest.class);
 
+        // observation
+        suite.addTestSuite(ObservationTest.class);
+
         return suite;
     }
 }
\ No newline at end of file

Added: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/observation/ObservationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/observation/ObservationTest.java?rev=821598&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/observation/ObservationTest.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/observation/ObservationTest.java Sun Oct  4 20:16:18 2009
@@ -0,0 +1,118 @@
+/*
+ * 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.jcr2spi.observation;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ObservationTest extends AbstractJCRTest {
+    private static Logger log = LoggerFactory.getLogger(ObservationTest.class);
+
+    private Node testNode;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        testNode = testRootNode.addNode(nodeName1);
+        testRootNode.save();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        testNode = null;
+        super.tearDown();
+    }
+
+    interface WaitableEventListener extends EventListener {
+        public void waitForEvent(int timeout) throws InterruptedException, RepositoryException;
+    }
+
+    /**
+     * Check whether an item with the path of an add node event exists.
+     * Regression test for JCR-2293.
+     * @throws RepositoryException
+     * @throws InterruptedException
+     */
+    public void testJCR_2293() throws RepositoryException, InterruptedException {
+        final String parentPath = testNode.getPath();
+        final String folderName = "folder_" + System.currentTimeMillis();
+        final Session session = getHelper().getReadWriteSession();
+
+        final Session session2 = getHelper().getReadOnlySession();
+        session2.getItem(parentPath);  // Don't remove. See JCR-2293.
+
+        WaitableEventListener eventListener = new WaitableEventListener() {
+            private RepositoryException failure;
+            private boolean done;
+
+            public synchronized void onEvent(final EventIterator events) {
+                try {
+                    while (events.hasNext()) {
+                        Event event = events.nextEvent();
+                        Item item2 = session2.getItem(event.getPath());
+                        assertEquals(parentPath + "/" + folderName, item2.getPath());
+                    }
+                }
+                catch (RepositoryException e) {
+                    failure = e;
+                }
+                finally {
+                    done = true;
+                    notifyAll();
+                }
+            }
+
+            public synchronized void waitForEvent(int timeout) throws InterruptedException, RepositoryException {
+                if (!done) {
+                    wait(timeout);
+                }
+                if (!done) {
+                    fail("Event listener not called");
+                }
+                if (failure != null) {
+                    throw failure;
+                }
+            }
+        };
+
+        session2.getWorkspace().getObservationManager()
+                .addEventListener(eventListener, Event.NODE_ADDED,
+                                                 parentPath, true, null, null, false);
+
+        Node parent = (Node) session.getItem(parentPath);
+        Node toDelete = parent.addNode(folderName, "nt:folder");
+        parent.save();
+
+        try {
+            eventListener.waitForEvent(60000);
+        }
+        finally {
+            toDelete.remove();
+            parent.save();
+            assertFalse(parent.hasNode(folderName));
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/observation/ObservationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native