You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2013/02/14 13:20:41 UTC

svn commit: r1446141 - in /jackrabbit/oak/trunk/oak-jcr/src: main/java/org/apache/jackrabbit/oak/jcr/ test/java/org/apache/jackrabbit/oak/jcr/

Author: mduerig
Date: Thu Feb 14 12:20:41 2013
New Revision: 1446141

URL: http://svn.apache.org/r1446141
Log:
OAK-606: Node becomes invalid after Session#move()
throw invalid item state exception on disconnected nodes

Added:
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveRemoveTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemDelegate.java?rev=1446141&r1=1446140&r2=1446141&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemDelegate.java Thu Feb 14 12:20:41 2013
@@ -83,8 +83,7 @@ public abstract class ItemDelegate {
      * @return  {@code true} iff stale
      */
     public boolean isStale() {
-        Status status = getLocationOrNull().getStatus();
-        return status == Status.DISCONNECTED || status == null;
+        return !getLocationInternal().exists();
     }
 
     /**
@@ -116,7 +115,7 @@ public abstract class ItemDelegate {
      */
     @Nonnull
     public TreeLocation getLocation() throws InvalidItemStateException {
-        TreeLocation location = getLocationOrNull();
+        TreeLocation location = getLocationInternal();
         if (!location.exists()) {
             throw new InvalidItemStateException("Item is stale");
         }
@@ -134,12 +133,12 @@ public abstract class ItemDelegate {
     /**
      * The underlying {@link org.apache.jackrabbit.oak.api.TreeLocation} of this item.
      * The location is only re-resolved when the revision of this item does not match
-     * the revision of the session.
+     * the revision of the session or when the location does not exist (anymore).
      * @return  tree location of the underlying item.
      */
     @Nonnull
-    private synchronized TreeLocation getLocationOrNull() {
-        if (location.exists() && sessionDelegate.getRevision() != revision) {
+    private synchronized TreeLocation getLocationInternal() {
+        if (sessionDelegate.getRevision() != revision || !location.exists()) {
             location = sessionDelegate.getLocation(location.getPath());
             revision = sessionDelegate.getRevision();
         }

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveRemoveTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveRemoveTest.java?rev=1446141&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveRemoveTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveRemoveTest.java Thu Feb 14 12:20:41 2013
@@ -0,0 +1,290 @@
+package org.apache.jackrabbit.oak.jcr;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class MoveRemoveTest extends AbstractRepositoryTest {
+
+    @Test
+    public void removeExistingNode() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("new");
+        session.save();
+
+        Node n = session.getNode("/new");
+        n.remove();
+
+        try {
+            n.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("new");
+        assertEquals("/new", n.getPath());
+    }
+
+    @Test
+    public void removeNewNode() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("new");
+
+        Node n = session.getNode("/new");
+        n.remove();
+
+        try {
+            n.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("new");
+        assertEquals("/new", n.getPath());
+    }
+
+    @Test
+    public void removeExistingNodeRefresh() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("new");
+        session.save();
+
+        Session session2 = createAdminSession();
+        Node n2 = session2.getNode("/new");
+
+        Node n = session.getNode("/new");
+        n.remove();
+        session.save();
+
+        assertEquals("/new", n2.getPath());
+
+        session2.refresh(true);
+        try {
+            n2.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("new");
+        session.save();
+        try {
+            n2.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session2.refresh(true);
+        assertEquals("/new", n2.getPath());
+
+        session2.logout();
+    }
+
+    @Test
+    public void removeExistingNodeParent() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("parent").addNode("new");
+        session.save();
+
+        Node n = session.getNode("/parent/new");
+        n.getParent().remove();
+
+        try {
+            n.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("parent").addNode("new");
+        assertEquals("/parent/new", n.getPath());
+    }
+
+    @Test
+    public void removeNewNodeParent() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("parent").addNode("new");
+
+        Node n = session.getNode("/parent/new");
+        n.getParent().remove();
+
+        try {
+            n.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("parent").addNode("new");
+        assertEquals("/parent/new", n.getPath());
+    }
+
+    @Test
+    public void removeExistingNodeRefreshParent() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("parent").addNode("new");
+        session.save();
+
+        Session session2 = createAdminSession();
+        Node n2 = session2.getNode("/parent/new");
+
+        Node n = session.getNode("/parent/new");
+        n.getParent().remove();
+        session.save();
+
+        assertEquals("/parent/new", n2.getPath());
+
+        session2.refresh(true);
+        try {
+            n2.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("parent").addNode("new");
+        session.save();
+        try {
+            n2.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session2.refresh(true);
+        assertEquals("/parent/new", n2.getPath());
+
+        session2.logout();
+    }
+
+    @Test
+    public void moveExistingNode() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("new");
+        session.save();
+
+        Node n = session.getNode("/new");
+        session.move("/new", "/moved");
+
+        try {
+            n.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("new");
+        assertEquals("/new", n.getPath());
+    }
+
+    @Test
+    public void moveNewNode() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("new");
+
+        Node n = session.getNode("/new");
+        session.move("/new", "/moved");
+
+        try {
+            n.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("new");
+        assertEquals("/new", n.getPath());
+    }
+
+    @Test
+    public void moveExistingNodeRefresh() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("new");
+        session.save();
+
+        Session session2 = createAdminSession();
+        Node n2 = session2.getNode("/new");
+
+        Node n = session.getNode("/new");
+        session.move("/new", "/moved");
+        session.save();
+
+        assertEquals("/new", n2.getPath());
+
+        session2.refresh(true);
+        try {
+            n2.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("new");
+        session.save();
+        try {
+            n2.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session2.refresh(true);
+        assertEquals("/new", n2.getPath());
+
+        session2.logout();
+    }
+
+    @Test
+    public void moveExistingParent() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("parent").addNode("new");
+        session.save();
+
+        Node n = session.getNode("/parent/new");
+        session.move("/parent", "/moved");
+
+        try {
+            n.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("parent").addNode("new");
+        assertEquals("/parent/new", n.getPath());
+    }
+
+    @Test
+    public void moveNewNodeParent() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("parent").addNode("new");
+
+        Node n = session.getNode("/parent/new");
+        session.move("/parent", "/moved");
+
+        try {
+            n.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("parent").addNode("new");
+        assertEquals("/parent/new", n.getPath());
+    }
+
+    @Test
+    public void moveExistingNodeRefreshParent() throws RepositoryException {
+        Session session = getAdminSession();
+        session.getRootNode().addNode("parent").addNode("new");
+        session.save();
+
+        Session session2 = createAdminSession();
+        Node n2 = session2.getNode("/parent/new");
+
+        Node n = session.getNode("/parent/new");
+        session.move("/parent", "/moved");
+        session.save();
+
+        assertEquals("/parent/new", n2.getPath());
+
+        session2.refresh(true);
+        try {
+            n2.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session.getRootNode().addNode("parent").addNode("new");
+        session.save();
+        try {
+            n2.getPath();
+            fail();
+        } catch (InvalidItemStateException e) {}
+
+        session2.refresh(true);
+        assertEquals("/parent/new", n2.getPath());
+
+        session2.logout();
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveRemoveTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveRemoveTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveTest.java?rev=1446141&r1=1446140&r2=1446141&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/MoveTest.java Thu Feb 14 12:20:41 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.jcr;
 
+import javax.jcr.InvalidItemStateException;
 import javax.jcr.Node;
 
 import org.apache.jackrabbit.JcrConstants;
@@ -35,46 +36,60 @@ public class MoveTest extends AbstractJC
         }
     }
 
-    @Ignore("OAK-606")
     @Test
     public void testRename() throws Exception {
         Node node1 = testRootNode.addNode(nodeName1);
         superuser.save();
 
-        String destPath = testRoot + '/' + nodeName2;
-        move(node1.getPath(), destPath, true);
+        String sourcePath = node1.getPath();
+        move(sourcePath, testRoot + '/' + nodeName2, true);
 
-        assertEquals(destPath, node1.getPath());
+        try {
+            node1.getPath();
+            fail();
+        } catch (InvalidItemStateException expected) {}
+
+        testRootNode.addNode(nodeName1);
+        assertEquals(sourcePath, node1.getPath());
     }
 
-    @Ignore("OAK-607")
     @Test
     public void testRenameNewNode() throws Exception {
         Node node1 = testRootNode.addNode(nodeName1);
 
-        String destPath = testRoot + '/' + nodeName2;
-        move(node1.getPath(), destPath, false);
+        String sourcePath = node1.getPath();
+        move(sourcePath, testRoot + '/' + nodeName2, false);
 
-        assertEquals(destPath, node1.getPath());
+        try {
+            node1.getPath();
+            fail();
+        } catch (InvalidItemStateException expected) {}
 
+        testRootNode.addNode(nodeName1);
         superuser.save();
-        assertEquals(destPath, node1.getPath());
+        assertEquals(sourcePath, node1.getPath());
     }
 
-    @Ignore("OAK-606")
     @Test
     public void testMove() throws Exception {
         Node node1 = testRootNode.addNode(nodeName1);
         Node node2 = testRootNode.addNode(nodeName2);
         superuser.save();
 
-        String destPath = node2.getPath() + '/' + nodeName1;
-        move(node1.getPath(), destPath, true);
+        String sourcePath = node1.getPath();
+        move(sourcePath, node2.getPath() + '/' + nodeName1, true);
 
-        assertEquals(destPath, node1.getPath());
+        try {
+            node1.getPath();
+            fail();
+        } catch (InvalidItemStateException expected) {}
+
+        testRootNode.addNode(nodeName1);
+        assertEquals(sourcePath, node1.getPath());
     }
 
     @Ignore("OAK-606")
+    @Test
     public void testMoveReferenceable() throws Exception {
         Node node1 = testRootNode.addNode(nodeName1);
         node1.addMixin(JcrConstants.MIX_REFERENCEABLE);
@@ -87,19 +102,22 @@ public class MoveTest extends AbstractJC
         assertEquals(destPath, node1.getPath());
     }
 
-    @Ignore("OAK-607")
     @Test
     public void testMoveNewNode() throws Exception {
         Node node1 = testRootNode.addNode(nodeName1);
         Node node2 = testRootNode.addNode(nodeName2);
 
-        String destPath = node2.getPath() + '/' + nodeName1;
-        move(node1.getPath(), destPath, false);
+        String sourcePath = node1.getPath();
+        move(sourcePath, node2.getPath() + '/' + nodeName1, false);
 
-        assertEquals(destPath, node1.getPath());
+        try {
+            node1.getPath();
+            fail();
+        } catch (InvalidItemStateException expected) {}
 
+        testRootNode.addNode(nodeName1);
         superuser.save();
-        assertEquals(destPath, node1.getPath());
+        assertEquals(sourcePath, node1.getPath());
     }
 
     @Ignore("OAK-607")

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java?rev=1446141&r1=1446140&r2=1446141&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java Thu Feb 14 12:20:41 2013
@@ -1627,6 +1627,7 @@ public class RepositoryTest extends Abst
         for (String parentPath : new String[] {"/", TEST_PATH}) {
             Node parent = session.getNode(parentPath);
             Node child = parent.addNode("child");
+            String childPath = child.getPath();
 
             child.remove();
             try {
@@ -1641,6 +1642,9 @@ public class RepositoryTest extends Abst
                 fail();
             }
             catch (InvalidItemStateException expected) { }
+
+            parent.addNode("child");
+            assertEquals(childPath, child.getPath());
         }
     }