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

svn commit: r771263 [1/2] - in /jackrabbit/trunk: jackrabbit-core/ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/ jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/

Author: reschke
Date: Mon May  4 10:36:18 2009
New Revision: 771263

URL: http://svn.apache.org/viewvc?rev=771263&view=rev
Log:
JCR-2085: move generic shareable node tests into jackrabbit-jcr-tests, add convenience method for checking supported node type (note that JCR-1773 still open; known.issues updated accordingly)

Added:
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/ShareableNodeTest.java   (with props)
Modified:
    jackrabbit/trunk/jackrabbit-core/pom.xml
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ShareableNodeTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/AbstractJCRTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/TestAll.java

Modified: jackrabbit/trunk/jackrabbit-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/pom.xml?rev=771263&r1=771262&r2=771263&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/pom.xml (original)
+++ jackrabbit/trunk/jackrabbit-core/pom.xml Mon May  4 10:36:18 2009
@@ -88,7 +88,7 @@
               <name>known.issues</name>
               <value>
                 org.apache.jackrabbit.core.xml.DocumentViewTest#testMultiValue
-                org.apache.jackrabbit.core.ShareableNodeTest#testSharedNodePath
+                org.apache.jackrabbit.test.api.ShareableNodeTest#testSharedNodePath
               </value>
             </property>
           </systemProperties>

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ShareableNodeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ShareableNodeTest.java?rev=771263&r1=771262&r2=771263&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ShareableNodeTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ShareableNodeTest.java Mon May  4 10:36:18 2009
@@ -16,28 +16,13 @@
  */
 package org.apache.jackrabbit.core;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-
-import javax.jcr.ImportUUIDBehavior;
 import javax.jcr.Item;
 import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.Workspace;
-import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.observation.Event;
 import javax.jcr.observation.EventIterator;
 import javax.jcr.observation.ObservationManager;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryResult;
-import javax.jcr.version.Version;
 
 import org.apache.jackrabbit.core.observation.SynchronousEventListener;
 import org.apache.jackrabbit.test.AbstractJCRTest;
@@ -46,134 +31,13 @@
  * Tests features available with shareable nodes.
  */
 public class ShareableNodeTest extends AbstractJCRTest {
-
+    
     //------------------------------------------------------ specification tests
 
     /**
-     * Verify that Node.getIndex returns the correct index in a shareable
-     * node (6.13).
-     */
-    public void testGetIndex() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        a2.addNode("b");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b", false);
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-        b1 = shared[0];
-        Node b2 = shared[1];
-
-        // verify indices of nodes b1/b2 in shared set
-        assertEquals(1, b1.getIndex());
-        assertEquals(2, b2.getIndex());
-    }
-
-    /**
-     * Verify that Node.getName returns the correct name in a shareable node
-     * (6.13).
-     */
-    public void testGetName() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-        b1 = shared[0];
-        Node b2 = shared[1];
-
-        // verify names of nodes b1/b2 in shared set
-        assertEquals("b1", b1.getName());
-        assertEquals("b2", b2.getName());
-    }
-
-    /**
-     * Verify that Node.getPath returns the correct path in a shareable
-     * node (6.13).
-     */
-    public void testGetPath() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-        b1 = shared[0];
-        Node b2 = shared[1];
-
-        // verify paths of nodes b1/b2 in shared set
-        assertEquals("/testroot/a1/b1", b1.getPath());
-        assertEquals("/testroot/a2/b2", b2.getPath());
-    }
-
-    /**
-     * Verify that the shareable node returned by Node.getNode() has the right
-     * name.
-     */
-    public void testGetNode() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // a1.getNode("b1") should return b1
-        b1 = a1.getNode("b1");
-        assertEquals("b1", b1.getName());
-
-        // a2.getNode("b2") should return b2
-        Node b2 = a2.getNode("b2");
-        assertEquals("b2", b2.getName());
-    }
-
-    /**
-     * Verify that the shareable nodes returned by Node.getNodes() have
-     * the right name.
+     * Verify that observation events are sent only once (6.13.15).
      */
-    public void testGetNodes() throws Exception {
+    public void testObservation() throws Exception {
         // setup parent nodes and first child
         Node a1 = testRootNode.addNode("a1");
         Node a2 = testRootNode.addNode("a2");
@@ -189,1343 +53,72 @@
         workspace.clone(workspace.getName(), b1.getPath(),
                 a2.getPath() + "/b2", false);
 
-        // a1.getNodes() should return b1
-        Node[] children = toArray(a1.getNodes());
-        assertEquals(1, children.length);
-        assertEquals("b1", children[0].getName());
-
-        // a2.getNodes() should return b2
-        children = toArray(a2.getNodes());
-        assertEquals(1, children.length);
-        assertEquals("b2", children[0].getName());
-    }
-
-    /**
-     * Verify that the shareable nodes returned by Node.getNodes(String) have
-     * the right name.
-     */
-    public void testGetNodesByPattern() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
+        // event listener that counts events received
+        class EventCounter implements SynchronousEventListener {
 
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
+            private int count;
 
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
+            public void onEvent(EventIterator events) {
+                while (events.hasNext()) {
+                    events.nextEvent();
+                    count++;
+                }
+            }
 
-        // a1.getNodes(*) should return b1
-        Node[] children = toArray(a1.getNodes("*"));
-        assertEquals(1, children.length);
-        assertEquals("b1", children[0].getName());
+            public int getEventCount() {
+                return count;
+            }
 
-        // a2.getNodes(*) should return b2
-        children = toArray(a2.getNodes("*"));
-        assertEquals(1, children.length);
-        assertEquals("b2", children[0].getName());
-    }
+            public void resetCount() {
+                count = 0;
+            }
+        }
 
-    /**
-     * Check new API Node.getSharedSet() (6.13.1)
-     */
-    public void testGetSharedSet() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
+        EventCounter el = new EventCounter();
+        ObservationManager om = superuser.getWorkspace().getObservationManager();
 
-        // add mixin
-        b1.addMixin("mix:shareable");
+        // add node underneath shared set: verify it generates one event only
+        om.addEventListener(el, Event.NODE_ADDED, testRootNode.getPath(),
+                true, null, null, false);
+        b1.addNode("c");
         b1.save();
+        superuser.getWorkspace().getObservationManager().removeEventListener(el);
+        assertEquals(1, el.getEventCount());
 
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // verify shared set contains 2 items
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-    }
-
-    /**
-     * Add the mix:shareable mixin to a node (6.13.2).
-     */
-    public void testAddMixin() throws Exception {
-        // setup parent node and first child
-        Node a = testRootNode.addNode("a");
-        Node b = a.addNode("b");
-        testRootNode.save();
-
-        b.addMixin("mix:shareable");
-        b.save();
-    }
-
-    /**
-     * Create a shareable node by restoring it (6.13.3).
-     */
-    public void testRestore() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // make b1 shareable
-        b1.addMixin("mix:shareable");
+        // remove node underneath shared set: verify it generates one event only
+        el.resetCount();
+        om.addEventListener(el, Event.NODE_REMOVED, testRootNode.getPath(),
+                true, null, null, false);
+        b1.getNode("c").remove();
         b1.save();
+        superuser.getWorkspace().getObservationManager().removeEventListener(el);
+        assertEquals(1, el.getEventCount());
 
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // make a2 versionable
-        a2.addMixin("mix:versionable");
-        a2.save();
-
-        // check in version and check out again
-        Version v = a2.checkin();
-        a2.checkout();
-
-        // delete b2 and save
-        a2.getNode("b2").remove();
-        a2.save();
-
-        // verify shared set contains one element only
-        Node[] shared = getSharedSet(b1);
-        assertEquals(1, shared.length);
-
-        // restore version
-        a2.restore(v, false);
-
-        // verify shared set contains again two elements
-        shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-    }
-
-
-    /**
-     * Check new API Node.removeShare() (6.13.4).
-     */
-    public void testRemoveShare() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
+        // add property underneath shared set: verify it generates one event only
+        el.resetCount();
+        om.addEventListener(el, Event.PROPERTY_ADDED, testRootNode.getPath(),
+                true, null, null, false);
+        b1.setProperty("c", "1");
         b1.save();
+        superuser.getWorkspace().getObservationManager().removeEventListener(el);
+        assertEquals(1, el.getEventCount());
 
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-        b1 = shared[0];
-        Node b2 = shared[1];
-
-        // remove b1 from shared set
-        ((NodeImpl) b1).removeShare();
-        a1.save();
-
-        // verify shared set of b2 contains only 1 item, namely b2 itself
-        shared = getSharedSet(b2);
-        assertEquals(1, shared.length);
-        assertTrue(shared[0].isSame(b2));
-    }
-
-    /**
-     * Check new API Node.removeSharedSet() (6.13.4).
-     */
-    public void testRemoveSharedSet() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
+        // modify property underneath shared set: verify it generates one event only
+        el.resetCount();
+        om.addEventListener(el, Event.PROPERTY_CHANGED, testRootNode.getPath(),
+                true, null, null, false);
+        b1.setProperty("c", "2");
         b1.save();
+        superuser.getWorkspace().getObservationManager().removeEventListener(el);
+        assertEquals(1, el.getEventCount());
 
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // remove shared set
-        ((NodeImpl) b1).removeSharedSet();
-        testRootNode.save();
-
-        // verify neither a1 nor a2 contain any more children
-        assertFalse(a1.hasNodes());
-        assertFalse(a2.hasNodes());
-    }
-
-    /**
-     * Invoke Node.removeSharedSet(), but save only one of the parent nodes
-     * of the shared set. This doesn't need to be supported according to the
-     * specification (6.13.4).
-     */
-    public void testRemoveSharedSetSaveOneParentOnly() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
+        // remove property underneath shared set: verify it generates one event only
+        el.resetCount();
+        om.addEventListener(el, Event.PROPERTY_REMOVED, testRootNode.getPath(),
+                true, null, null, false);
+        b1.getProperty("c").remove();
         b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // remove shared set
-        ((NodeImpl) b1).removeSharedSet();
-
-        try {
-            // save only one of the parents, should fail
-            a1.save();
-            fail("Removing a shared set requires saving all parents.");
-        } catch (ConstraintViolationException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Verify that shareable nodes in the same shared set have the same
-     * jcr:uuid (6.13.10).
-     */
-    public void testSameUUID() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-        b1 = shared[0];
-        Node b2 = shared[1];
-
-        // verify nodes in a shared set have the same jcr:uuid
-        assertTrue(b1.getUUID().equals(b2.getUUID()));
-    }
-
-    /**
-     * Add a child to a shareable node and verify that another node in the
-     * same shared set has the same child and is modified when the first
-     * one is (6.13.11).
-     */
-    public void testAddChild() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-        b1 = shared[0];
-        Node b2 = shared[1];
-
-        // add node to b1, verify b2 is modified as well and contains that child
-        b1.addNode("c");
-        assertTrue(b2.isModified());
-        assertTrue(b2.hasNode("c"));
-        b1.save();
-    }
-
-    /**
-     * Copy a subtree that contains shareable nodes. Verify that the nodes
-     * newly created are not in the shared set that existed before the copy,
-     * but if two nodes in the source of a copy are in the same shared set, then
-     * the two corresponding nodes in the destination of the copy must also be
-     * in the same shared set (6.13.12).
-     */
-    public void testCopy() throws Exception {
-        // setup parent node and first child
-        Node s = testRootNode.addNode("s");
-        Node a1 = s.addNode("a1");
-        Node a2 = s.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // copy source tree to destination
-        workspace.copy(s.getPath(), testRootNode.getPath() + "/d");
-
-        // verify source contains shared set with 2 entries
-        Node[] shared1 = getSharedSet(b1);
-        assertEquals(2, shared1.length);
-
-        // verify destination contains shared set with 2 entries
-        Node[] shared2 = getSharedSet(testRootNode.getNode("d/a1/b1"));
-        assertEquals(2, shared2.length);
-
-        // verify elements in source shared set and destination shared set
-        // don't have the same UUID
-        String srcUUID = shared1[0].getUUID();
-        String destUUID = shared2[0].getUUID();
-        assertFalse(
-                "Source and destination of a copy must not have the same UUID",
-                srcUUID.equals(destUUID));
-    }
-
-    /**
-     * Verify that a share cycle is detected (6.13.13) when a shareable node
-     * is cloned.
-     */
-    public void testDetectShareCycleOnClone() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        Workspace workspace = b1.getSession().getWorkspace();
-
-        try {
-            // clone underneath b1: this must fail
-            workspace.clone(workspace.getName(), b1.getPath(),
-                    b1.getPath() + "/c", false);
-            fail("Share cycle not detected on clone.");
-        } catch (RepositoryException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Verify that a share cycle is detected (6.13.13) when a node is moved.
-     */
-    public void testDetectShareCycleOnMove() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child node
-        Node c = b1.addNode("c");
-        b1.save();
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-
-        // move node
-        try {
-            workspace.move(testRootNode.getPath() + "/a2", c.getPath() + "/d");
-            fail("Share cycle not detected on move.");
-        } catch (RepositoryException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Verify that a share cycle is detected (6.13.13) when a node is
-     * transiently moved.
-     */
-    public void testDetectShareCycleOnTransientMove() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Session session = b1.getSession();
-        Workspace workspace = session.getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child node
-        Node c = b1.addNode("c");
-        b1.save();
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-
-        // move node
-        try {
-            session.move(testRootNode.getPath() + "/a2", c.getPath());
-            fail("Share cycle not detected on transient move.");
-        } catch (RepositoryException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Verify export and import of a tree containing multiple nodes in the
-     * same shared set (6.13.14). The first serialized node in that shared
-     * set is serialized in the normal fashion (with all of its properties
-     * and children), but any subsequent shared node in that shared set is
-     * serialized as a special node of type <code>nt:share</code>, which
-     * contains only the <code>jcr:uuid</code> property of the shared node
-     * and the <code>jcr:primaryType</code> property indicating the type
-     * <code>nt:share</code>.
-     */
-    public void testImportExportNtShare() throws Exception {
-        // setup parent nodes and first child
-        Node p = testRootNode.addNode("p");
-        Node a1 = p.addNode("a1");
-        Node a2 = p.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Session session = b1.getSession();
-        Workspace workspace = session.getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // create temp file
-        File tmpFile = File.createTempFile("test", null);
-        tmpFile.deleteOnExit();
-
-        // export system view of /p
-        OutputStream out = new FileOutputStream(tmpFile);
-        try {
-            session.exportSystemView(p.getPath(), out, false, false);
-        } finally {
-            out.close();
-        }
-
-        // delete p and save
-        p.remove();
-        testRootNode.save();
-
-        // and import again underneath test root
-        InputStream in = new FileInputStream(tmpFile);
-        try {
-            workspace.importXML(testRootNode.getPath(), in,
-                    ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
-        } finally {
-            in.close();
-        }
-
-        // verify shared set consists of two nodes
-        Node[] shared = getSharedSet(testRootNode.getNode("p/a1/b1"));
-        assertEquals(2, shared.length);
-    }
-
-    /**
-     * Verify system view import via workspace (6.13.14). Export a system view
-     * containing a shareable node and verify, that reimporting underneath
-     * a different parent adds another member to the shared set and does not
-     * duplicate children nodes.
-     */
-    public void testImportSystemViewCollision() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node a3 = testRootNode.addNode("a3");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Session session = b1.getSession();
-        Workspace workspace = session.getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child c to shareable nodes b1 & b2
-        b1.addNode("c");
-        b1.save();
-
-        // create temp file
-        File tmpFile = File.createTempFile("test", null);
-        tmpFile.deleteOnExit();
-
-        // export system view of /a1/b1
-        OutputStream out = new FileOutputStream(tmpFile);
-        try {
-            session.exportSystemView(b1.getPath(), out, false, false);
-        } finally {
-            out.close();
-        }
-
-        // and import again underneath /a3
-        InputStream in = new FileInputStream(tmpFile);
-        try {
-            workspace.importXML(a3.getPath(), in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
-        } finally {
-            in.close();
-        }
-
-        // verify there's another element in the shared set
-        Node[] shared = getSharedSet(b1);
-        assertEquals(3, shared.length);
-
-        // verify child c has not been duplicated
-        Node[] children = toArray(b1.getNodes());
-        assertEquals(1, children.length);
-    }
-
-    /**
-     * Verify document view import via workspace (6.13.14). Export a document
-     * view containing a shareable node and verify, that reimporting
-     * underneath a different parent adds another member to the shared set and
-     * does not duplicate children nodes.
-     */
-    public void testImportDocumentViewCollision() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node a3 = testRootNode.addNode("a3");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Session session = b1.getSession();
-        Workspace workspace = session.getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child c to shareable nodes b1 & b2
-        b1.addNode("c");
-        b1.save();
-
-        // create temp file
-        File tmpFile = File.createTempFile("test", null);
-        tmpFile.deleteOnExit();
-
-        // export system view of /a1/b1
-        OutputStream out = new FileOutputStream(tmpFile);
-        try {
-            session.exportDocumentView(b1.getPath(), out, false, false);
-        } finally {
-            out.close();
-        }
-
-        // and import again underneath /a3
-        InputStream in = new FileInputStream(tmpFile);
-        try {
-            workspace.importXML(a3.getPath(), in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
-        } finally {
-            in.close();
-        }
-
-        // verify there's another element in the shared set
-        Node[] shared = getSharedSet(b1);
-        assertEquals(3, shared.length);
-
-        // verify child c has not been duplicated
-        Node[] children = toArray(b1.getNodes());
-        assertEquals(1, children.length);
-    }
-
-    /**
-     * Verify system view import via session (6.13.14). Export a system view
-     * containing a shareable node and verify, that reimporting underneath
-     * a different parent adds another member to the shared set and does not
-     * duplicate children nodes.
-     */
-    public void testSessionImportSystemViewCollision() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node a3 = testRootNode.addNode("a3");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Session session = b1.getSession();
-        Workspace workspace = session.getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child c to shareable nodes b1 & b2
-        b1.addNode("c");
-        b1.save();
-
-        // create temp file
-        File tmpFile = File.createTempFile("test", null);
-        tmpFile.deleteOnExit();
-
-        // export system view of /a1/b1
-        OutputStream out = new FileOutputStream(tmpFile);
-        try {
-            session.exportSystemView(b1.getPath(), out, false, false);
-        } finally {
-            out.close();
-        }
-
-        // and import again underneath /a3
-        InputStream in = new FileInputStream(tmpFile);
-        try {
-            session.importXML(a3.getPath(), in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
-            session.save();
-        } finally {
-            in.close();
-        }
-
-        // verify there's another element in the shared set
-        Node[] shared = getSharedSet(b1);
-        assertEquals(3, shared.length);
-
-        // verify child c has not been duplicated
-        Node[] children = toArray(b1.getNodes());
-        assertEquals(1, children.length);
-    }
-
-    /**
-     * Verify document view import via session (6.13.14). Export a document
-     * view containing a shareable node and verify, that reimporting
-     * underneath a different parent adds another member to the shared set and
-     * does not duplicate children nodes.
-     */
-    public void testSessionImportDocumentViewCollision() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node a3 = testRootNode.addNode("a3");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Session session = b1.getSession();
-        Workspace workspace = session.getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child c to shareable nodes b1 & b2
-        b1.addNode("c");
-        b1.save();
-
-        // create temp file
-        File tmpFile = File.createTempFile("test", null);
-        tmpFile.deleteOnExit();
-
-        // export system view of /a1/b1
-        OutputStream out = new FileOutputStream(tmpFile);
-        try {
-            session.exportSystemView(b1.getPath(), out, false, false);
-        } finally {
-            out.close();
-        }
-
-        // and import again underneath /a3
-        InputStream in = new FileInputStream(tmpFile);
-        try {
-            session.importXML(a3.getPath(), in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
-            session.save();
-        } finally {
-            in.close();
-        }
-
-        // verify there's another element in the shared set
-        Node[] shared = getSharedSet(b1);
-        assertEquals(3, shared.length);
-
-        // verify child c has not been duplicated
-        Node[] children = toArray(b1.getNodes());
-        assertEquals(1, children.length);
-    }
-
-    /**
-     * Verify that observation events are sent only once (6.13.15).
-     */
-    public void testObservation() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // event listener that counts events received
-        class EventCounter implements SynchronousEventListener {
-
-            private int count;
-
-            public void onEvent(EventIterator events) {
-                while (events.hasNext()) {
-                    events.nextEvent();
-                    count++;
-                }
-            }
-
-            public int getEventCount() {
-                return count;
-            }
-
-            public void resetCount() {
-                count = 0;
-            }
-        }
-
-        EventCounter el = new EventCounter();
-        ObservationManager om = superuser.getWorkspace().getObservationManager();
-
-        // add node underneath shared set: verify it generates one event only
-        om.addEventListener(el, Event.NODE_ADDED, testRootNode.getPath(),
-                true, null, null, false);
-        b1.addNode("c");
-        b1.save();
-        superuser.getWorkspace().getObservationManager().removeEventListener(el);
-        assertEquals(1, el.getEventCount());
-
-        // remove node underneath shared set: verify it generates one event only
-        el.resetCount();
-        om.addEventListener(el, Event.NODE_REMOVED, testRootNode.getPath(),
-                true, null, null, false);
-        b1.getNode("c").remove();
-        b1.save();
-        superuser.getWorkspace().getObservationManager().removeEventListener(el);
-        assertEquals(1, el.getEventCount());
-
-        // add property underneath shared set: verify it generates one event only
-        el.resetCount();
-        om.addEventListener(el, Event.PROPERTY_ADDED, testRootNode.getPath(),
-                true, null, null, false);
-        b1.setProperty("c", "1");
-        b1.save();
-        superuser.getWorkspace().getObservationManager().removeEventListener(el);
-        assertEquals(1, el.getEventCount());
-
-        // modify property underneath shared set: verify it generates one event only
-        el.resetCount();
-        om.addEventListener(el, Event.PROPERTY_CHANGED, testRootNode.getPath(),
-                true, null, null, false);
-        b1.setProperty("c", "2");
-        b1.save();
-        superuser.getWorkspace().getObservationManager().removeEventListener(el);
-        assertEquals(1, el.getEventCount());
-
-        // remove property underneath shared set: verify it generates one event only
-        el.resetCount();
-        om.addEventListener(el, Event.PROPERTY_REMOVED, testRootNode.getPath(),
-                true, null, null, false);
-        b1.getProperty("c").remove();
-        b1.save();
-        superuser.getWorkspace().getObservationManager().removeEventListener(el);
-        assertEquals(1, el.getEventCount());
-    }
-
-    /**
-     * Verify that a lock applies to all nodes in a shared set (6.13.16).
-     */
-    public void testLock() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        a1.addMixin("mix:lockable");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.addMixin("mix:lockable");
-        b1.save();
-
-        // add child c
-        Node c = b1.addNode("c");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-        b1 = shared[0];
-        Node b2 = shared[1];
-
-        // lock shareable node -> all nodes in shared set are locked
-        b1.lock(false, true);
-        try {
-            assertTrue(b2.isLocked());
-        } finally {
-            b1.unlock();
-        }
-
-        // deep-lock parent -> locks (common) child node
-        a1.lock(true, true);
-        try {
-            assertTrue(c.isLocked());
-        } finally {
-            a1.unlock();
-        }
-    }
-
-    /**
-     * Restore a shareable node that automatically removes an existing shareable
-     * node (6.13.19). In this case the particular shared node is removed but
-     * its descendants continue to exist below the remaining members of the
-     * shared set.
-     */
-    public void testRestoreRemoveExisting() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // make b1 shareable
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child c
-        b1.addNode("c");
-        b1.save();
-
-        // make a2 versionable
-        a2.addMixin("mix:versionable");
-        a2.save();
-
-        // check in version and check out again
-        Version v = a2.checkin();
-        a2.checkout();
-
-        // delete b2 and save
-        a2.getNode("b2").remove();
-        a2.save();
-
-        // verify shareable set contains one elements only
-        Node[] shared = getSharedSet(b1);
-        assertEquals(1, shared.length);
-
-        // restore version and remove existing (i.e. b1)
-        a2.restore(v, true);
-
-        // verify shareable set contains still one element
-        shared = getSharedSet(a2.getNode("b2"));
-        assertEquals(1, shared.length);
-
-        // verify child c still exists
-        Node[] children = toArray(a2.getNode("b2").getNodes());
-        assertEquals(1, children.length);
-    }
-
-    /**
-     * Clone a mix:shareable node to the same workspace (6.13.20). Verify
-     * that cloning without mix:shareable fails.
-     */
-    public void testClone() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        Workspace workspace = b1.getSession().getWorkspace();
-
-        try {
-            // clone (1st attempt, without mix:shareable, should fail)
-            workspace.clone(workspace.getName(), b1.getPath(),
-                    a2.getPath() + "/b2", false);
-            fail("Cloning a node into the same workspace should fail.");
-        } catch (RepositoryException e) {
-            // expected
-        }
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone (2nd attempt, with mix:shareable)
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-    }
-
-    /**
-     * Verify that Node.isSame returns <code>true</code> for shareable nodes
-     * in the same shared set (6.13.21)
-     */
-    public void testIsSame() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        Node[] shared = getSharedSet(b1);
-        assertEquals(2, shared.length);
-        b1 = shared[0];
-        Node b2 = shared[1];
-
-        // verify b1 is same as b2 (and vice-versa)
-        assertTrue(b1.isSame(b2));
-        assertTrue(b2.isSame(b1));
-    }
-
-    /**
-     * Remove mix:shareable from a shareable node. This is unsupported in
-     * Jackrabbit (6.13.22).
-     */
-    public void testRemoveMixin() throws Exception {
-        // setup parent node and first child
-        Node a = testRootNode.addNode("a");
-        Node b = a.addNode("b");
-        testRootNode.save();
-
-        // add mixin
-        b.addMixin("mix:shareable");
-        b.save();
-
-        try {
-            // remove mixin
-            b.removeMixin("mix:shareable");
-            b.save();
-            fail("Removing mix:shareable should fail.");
-        } catch (UnsupportedRepositoryOperationException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Verify that a descendant of a shareable node appears once in the
-     * result set (6.13.23)
-     */
-    public void testSearch() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add new referenceable child
-        Node c = b1.addNode("c");
-        c.addMixin(mixReferenceable);
-        b1.save();
-
-        String sql = "SELECT * FROM nt:unstructured WHERE jcr:uuid = '"+c.getUUID()+"'";
-        QueryResult res = workspace.getQueryManager().createQuery(sql, Query.SQL).execute();
-
-        ArrayList list = new ArrayList();
-
-        NodeIterator iter = res.getNodes();
-        while (iter.hasNext()) {
-            list.add(iter.nextNode());
-        }
-        assertEquals(1, list.size());
-        assertTrue(((Node) list.get(0)).isSame(c));
-    }
-
-    //--------------------------------------------------------- limitation tests
-
-    /**
-     * Clone a mix:shareable node to the same workspace, with the same
-     * parent. This is unsupported in Jackrabbit.
-     */
-    public void testCloneToSameParent() throws Exception {
-        // setup parent nodes and first child
-        Node a = testRootNode.addNode("a");
-        Node b1 = a.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        Workspace workspace = b1.getSession().getWorkspace();
-
-        try {
-            // clone to same parent
-            workspace.clone(workspace.getName(), b1.getPath(),
-                    a.getPath() + "/b2", false);
-            fail("Cloning inside same parent should fail.");
-        } catch (UnsupportedRepositoryOperationException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Move a node in a shared set. This is unsupported in Jackrabbit.
-     */
-    public void testMoveShareableNode() throws Exception {
-        // setup parent nodes and first childs
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b = a1.addNode("b");
-        testRootNode.save();
-
-        // add mixin
-        b.addMixin("mix:shareable");
-        b.save();
-
-        // move
-        Workspace workspace = b.getSession().getWorkspace();
-
-        try {
-            // move shareable node
-            workspace.move(b.getPath(), a2.getPath() + "/b");
-            fail("Moving a mix:shareable should fail.");
-        } catch (UnsupportedRepositoryOperationException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Transiently move a node in a shared set. This is unsupported in
-     * Jackrabbit.
-     */
-    public void testTransientMoveShareableNode() throws Exception {
-        // setup parent nodes and first childs
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b = a1.addNode("b");
-        testRootNode.save();
-
-        // add mixin
-        b.addMixin("mix:shareable");
-        b.save();
-
-        // move
-        Session session = superuser;
-
-        try {
-            // move shareable node
-            session.move(b.getPath(), a2.getPath() + "/b");
-            session.save();
-            fail("Moving a mix:shareable should fail.");
-        } catch (UnsupportedRepositoryOperationException e) {
-            // expected
-        }
-    }
-
-    //----------------------------------------------------- implementation tests
-
-    /**
-     * Verify that invoking save() on a share-ancestor will save changes in
-     * all share-descendants.
-     */
-    public void testRemoveDescendantAndSave() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Session session = b1.getSession();
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child node c to b1
-        Node c = b1.addNode("c");
-        b1.save();
-
-        // remove child node c
-        c.remove();
-
-        // save a2 (having path /testroot/a2): this should save c as well
-        // since one of the paths to c is /testroot/a2/b2/c
-        a2.save();
-        assertFalse("Saving share-ancestor should save share-descendants",
-                session.hasPendingChanges());
-    }
-
-    /**
-     * Verify that invoking save() on a share-ancestor will save changes in
-     * all share-descendants.
-     */
-    public void testRemoveDescendantAndRemoveShareAndSave() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Session session = b1.getSession();
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child node c to b1
-        Node c = b1.addNode("c");
-        b1.save();
-
-        // remove child node c
-        c.remove();
-
-        // remove share b2 from a2
-        ((NodeImpl) a2.getNode("b2")).removeShare();
-
-        // save a2 (having path /testroot/a2): this should save c as well
-        // since one of the paths to c was /testroot/a2/b2/c
-        a2.save();
-        assertFalse("Saving share-ancestor should save share-descendants",
-                session.hasPendingChanges());
-    }
-
-    /**
-     * Verify that invoking save() on a share-ancestor will save changes in
-     * all share-descendants.
-     */
-    public void testModifyDescendantAndSave() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child node c to b1
-        Node c = b1.addNode("c");
-        b1.save();
-
-        // add child d to c, this modifies c
-        c.addNode("d");
-
-        // save a2 (having path /testroot/a2): this should save c as well
-        // since one of the paths to c is /testroot/a2/b2/c
-        a2.save();
-        assertFalse("Saving share-ancestor should save share-descendants",
-                c.isModified());
-    }
-
-    /**
-     * Verify that invoking save() on a share-ancestor will save changes in
-     * all share-descendants.
-     */
-    public void testModifyDescendantAndRemoveShareAndSave() throws Exception {
-        // setup parent nodes and first child
-        Node a1 = testRootNode.addNode("a1");
-        Node a2 = testRootNode.addNode("a2");
-        Node b1 = a1.addNode("b1");
-        testRootNode.save();
-
-        // add mixin
-        b1.addMixin("mix:shareable");
-        b1.save();
-
-        // clone
-        Workspace workspace = b1.getSession().getWorkspace();
-        workspace.clone(workspace.getName(), b1.getPath(),
-                a2.getPath() + "/b2", false);
-
-        // add child node c to b1
-        Node c = b1.addNode("c");
-        b1.save();
-
-        // add child d to c, this modifies c
-        c.addNode("d");
-
-        // remove share b2 from a2
-        ((NodeImpl) a2.getNode("b2")).removeShare();
-
-        // save a2 (having path /testroot/a2): this should save c as well
-        // since one of the paths to c was /testroot/a2/b2/c
-        a2.save();
-        assertFalse("Saving share-ancestor should save share-descendants",
-                c.isModified());
-    }
-
-    /**
-     * Clone a mix:shareable node to the same workspace multiple times, remove
-     * all parents and save. Exposes an error that occurred when having more
-     * than two members in a shared set and parents were removed in the same
-     * order they were created.
-     */
-    public void testCloneMultipleTimes() throws Exception {
-        final int count = 10;
-        Node[] parents = new Node[count];
-
-        // setup parent nodes and first child
-        for (int i = 0; i < parents.length; i++) {
-            parents[i] = testRootNode.addNode("a" + (i + 1));
-        }
-        Node b = parents[0].addNode("b");
-        testRootNode.save();
-
-        // add mixin
-        b.addMixin("mix:shareable");
-        b.save();
-
-        Workspace workspace = b.getSession().getWorkspace();
-
-        // clone to all other nodes
-        for (int i = 1; i < parents.length; i++) {
-            workspace.clone(workspace.getName(), b.getPath(),
-                    parents[i].getPath() + "/b", false);
-        }
-
-        // remove all parents and save
-        for (int i = 0; i < parents.length; i++) {
-            parents[i].remove();
-        }
-        testRootNode.save();
-    }
-
-    /**
-     * Verify that shared nodes return correct paths.
-     */
-    public void testSharedNodePath() throws Exception {
-       Node a1 = testRootNode.addNode("a1");
-       Node a2 = a1.addNode("a2");
-       Node b1 = a1.addNode("b1");
-       b1.addMixin("mix:shareable");
-       testRootNode.save();
-
-       //now we have a shareable node N with path a1/b1
-
-       Session session = testRootNode.getSession();
-       Workspace workspace = session.getWorkspace();
-       String path = a2.getPath() + "/b2";
-       workspace.clone(workspace.getName(), b1.getPath(), path, false);
-
-       //now we have another shareable node N' in the same shared set as N with path a1/a2/b2
-
-       //using the path a1/a2/b2, we should get the node N' here
-       Item item = session.getItem(path);
-       assertEquals("unexpectedly got the path from another node from the same shared set", path, item.getPath()); 
-    } 
-    
-    //---------------------------------------------------------- utility methods
-
-    /**
-     * Return a shared set as an array of nodes.
-     *
-     * @param n node
-     * @return array of nodes in shared set
-     */
-    private static Node[] getSharedSet(Node n) throws RepositoryException {
-        return toArray(((NodeImpl) n).getSharedSet());
-    }
-
-    /**
-     * Return an array of nodes given a <code>NodeIterator</code>.
-     *
-     * @param iter node iterator
-     * @return node array
-     */
-    private static Node[] toArray(NodeIterator iter) {
-        ArrayList list = new ArrayList();
-
-        while (iter.hasNext()) {
-            list.add(iter.nextNode());
-        }
-
-        Node[] result = new Node[list.size()];
-        list.toArray(result);
-        return result;
+        superuser.getWorkspace().getObservationManager().removeEventListener(el);
+        assertEquals(1, el.getEventCount());
     }
 }

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/AbstractJCRTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/AbstractJCRTest.java?rev=771263&r1=771262&r2=771263&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/AbstractJCRTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/AbstractJCRTest.java Mon May  4 10:36:18 2009
@@ -29,6 +29,7 @@
 import javax.jcr.RangeIterator;
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
 import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NodeType;
@@ -689,6 +690,21 @@
     }
 
     /**
+     * Checks that the repository supports the specified node type, otherwise aborts with
+     * {@link NotExecutableException}
+     * @throws NotExecutableException when the specified node type is unknown
+     */
+    protected void ensureKnowsNodeType(Session session, String nodetype) throws NotExecutableException, RepositoryException {
+        
+        try {
+            session.getWorkspace().getNodeTypeManager().getNodeType(nodetype);
+        }
+        catch (NoSuchNodeTypeException ex) {
+            throw new NotExecutableException("Repository does not support node type " + nodetype);
+        }
+    }
+    
+    /**
      * Checks whether the node already has the specified mixin node type
      */
     protected boolean needsMixin(Node node, String mixin) throws RepositoryException {