/* * 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.exoplatform.services.jcr.api.core.query; import javax.jcr.Session; import javax.jcr.RepositoryException; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.InvalidItemStateException; import javax.jcr.query.Query; import javax.jcr.query.QueryResult; import javax.jcr.query.QueryManager; /** * Tests if the NodeIterator returned by {@link javax.jcr.query.QueryResult#getNodes()} * skips Nodes that have been deleted in the meantime. */ public class SkipDeletedNodesTest extends AbstractQueryTest { private Session s2; private QueryManager qm; protected void setUp() throws Exception { super.setUp(); s2 = helper.getSuperuserSession(); qm = s2.getWorkspace().getQueryManager(); } protected void tearDown() throws Exception { try { if (s2 != null) { s2.logout(); s2 = null; } } finally { qm = null; super.tearDown(); } } /** * Executes a query with one session and removes a node from that query * result with another session. */ public void testRemoveFirstNode() throws RepositoryException { Node n1 = testRootNode.addNode("node1"); testRootNode.addNode("node2"); testRootNode.addNode("node3"); testRootNode.save(); // query the workspace for all three nodes String stmt = testPath + "/*"; QueryResult res = qm.createQuery(stmt, Query.XPATH).execute(); // now remove the first node n1.remove(); testRootNode.save(); // iterate over nodes log.println("Result nodes:"); int count = 0; for (NodeIterator it = res.getNodes(); it.hasNext(); ) { assertEquals("Wrong value for getPosition().", count++, it.getPosition()); try { log.println(it.nextNode().getPath()); } catch (InvalidItemStateException e) { // this is allowed log.println("Invalid: <deleted>"); } } } /** * Executes a query with one session and removes a node from that query * result with another session. */ public void testRemoveSomeNode() throws RepositoryException { testRootNode.addNode("node1"); Node n2 = testRootNode.addNode("node2"); testRootNode.addNode("node3"); testRootNode.save(); // query the workspace for all three nodes String stmt = testPath + "/*"; QueryResult res = qm.createQuery(stmt, Query.XPATH).execute(); // now remove the second node n2.remove(); testRootNode.save(); // iterate over nodes int count = 0; log.println("Result nodes:"); for (NodeIterator it = res.getNodes(); it.hasNext(); ) { assertEquals("Wrong value for getPosition().", count++, it.getPosition()); try { log.println(it.nextNode().getPath()); } catch (InvalidItemStateException e) { // this is allowed log.println("Invalid: <deleted>"); } } } /** * Executes a query with one session and removes a node from that query * result with another session. */ public void testRemoveLastNode() throws RepositoryException { testRootNode.addNode("node1"); testRootNode.addNode("node2"); Node n3 = testRootNode.addNode("node3"); testRootNode.save(); // query the workspace for all three nodes String stmt = testPath + "/*"; QueryResult res = qm.createQuery(stmt, Query.XPATH).execute(); // now remove the last node n3.remove(); testRootNode.save(); // iterate over nodes int count = 0; log.println("Result nodes:"); for (NodeIterator it = res.getNodes(); it.hasNext(); ) { assertEquals("Wrong value for getPosition().", count++, it.getPosition()); try { log.println(it.nextNode().getPath()); } catch (InvalidItemStateException e) { // this is allowed log.println("Invalid: <deleted>"); } } } /** * Executes a query with one session and removes a node from that query * result with another session. * </p>This test is different from the other tests that it removes the * node after another session has called hasNext() to retrieve the node * that gets deleted. */ public void testRemoveFirstNodeAfterHasNext() throws RepositoryException { Node n1 = testRootNode.addNode("node1"); testRootNode.addNode("node2"); testRootNode.addNode("node3"); testRootNode.save(); // query the workspace for all three nodes String stmt = testPath + "/*"; QueryResult res = qm.createQuery(stmt, Query.XPATH).execute(); NodeIterator it = res.getNodes(); it.hasNext(); // now remove the first node n1.remove(); testRootNode.save(); // iterate over nodes int count = 0; log.println("Result nodes:"); while (it.hasNext()) { assertEquals("Wrong value for getPosition().", count++, it.getPosition()); try { log.println(it.nextNode().getPath()); } catch (InvalidItemStateException e) { // this is allowed log.println("Invalid: <deleted>"); } } } /** * Executes a query with one session and removes a node from that query * result with another session. * </p>This test is different from the other tests that it removes the * node after another session has called hasNext() to retrieve the node * that gets deleted. */ public void testRemoveSomeNodeAfterHasNext() throws RepositoryException { testRootNode.addNode("node1"); Node n2 = testRootNode.addNode("node2"); testRootNode.addNode("node3"); testRootNode.save(); // query the workspace for all three nodes String stmt = testPath + "/*"; QueryResult res = qm.createQuery(stmt, Query.XPATH).execute(); NodeIterator it = res.getNodes(); it.hasNext(); // now remove the second node n2.remove(); testRootNode.save(); // iterate over nodes int count = 0; log.println("Result nodes:"); while (it.hasNext()) { assertEquals("Wrong value for getPosition().", count++, it.getPosition()); try { log.println(it.nextNode().getPath()); } catch (InvalidItemStateException e) { // this is allowed log.println("Invalid: <deleted>"); } } } }