Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 97080 invoked from network); 20 Oct 2008 13:17:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 20 Oct 2008 13:17:20 -0000 Received: (qmail 13273 invoked by uid 500); 20 Oct 2008 13:17:22 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 13186 invoked by uid 500); 20 Oct 2008 13:17:22 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 13177 invoked by uid 99); 20 Oct 2008 13:17:22 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Oct 2008 06:17:21 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Oct 2008 13:16:12 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 6D95D238896B; Mon, 20 Oct 2008 06:16:50 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r706273 - in /jackrabbit/trunk/jackrabbit-jcr2spi/src: main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java test/java/org/apache/jackrabbit/jcr2spi/IsSameTest.java test/java/org/apache/jackrabbit/jcr2spi/TestAll.java Date: Mon, 20 Oct 2008 13:16:49 -0000 To: commits@jackrabbit.apache.org From: angela@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20081020131650.6D95D238896B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: angela Date: Mon Oct 20 06:16:49 2008 New Revision: 706273 URL: http://svn.apache.org/viewvc?rev=706273&view=rev Log: JCR-1821: Item.isSame may return wrong result if any ancestor is invalidated Added: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/IsSameTest.java (with props) Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.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/ItemImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java?rev=706273&r1=706272&r2=706273&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java (original) +++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemImpl.java Mon Oct 20 06:16:49 2008 @@ -26,6 +26,7 @@ import org.apache.jackrabbit.jcr2spi.operation.Operation; import org.apache.jackrabbit.jcr2spi.util.LogUtil; import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour; +import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry; import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry; import org.apache.jackrabbit.spi.Path; import org.apache.jackrabbit.spi.Name; @@ -183,11 +184,17 @@ if (this == otherItem) { return true; } + if (isNode() != otherItem.isNode()) { + return false; + } if (otherItem instanceof ItemImpl) { ItemImpl other = (ItemImpl) otherItem; if (this.state == other.state) { return true; } + // check status of the other item. + other.checkStatus(); + // 2 items may only be the same if the were accessed from Sessions // bound to the same workspace String otherWspName = other.session.getWorkspace().getName(); @@ -195,6 +202,10 @@ // in addition they must provide the same id irrespective of // any transient modifications. if (state.getStatus() != Status.NEW && other.state.getStatus() != Status.NEW ) { + // if any ancestor is _invalidated_ force it's reload in + // order to detect id changes. + updateId(state); + updateId(other.state); return state.getWorkspaceId().equals(other.state.getWorkspaceId()); } /* else: @@ -205,7 +216,7 @@ - either of the two items does not have a workspace state. therefore the items cannot be the same, since one has been transiently added in one but not the other session. - */ + */ } } return false; @@ -531,4 +542,22 @@ String safeGetJCRPath() { return LogUtil.safeGetJCRPath(getItemState(), session.getPathResolver()); } + + /** + * + * @param state + * @throws RepositoryException + */ + private static void updateId(ItemState state) throws RepositoryException { + HierarchyEntry he = state.getHierarchyEntry(); + while (he.getStatus() != Status.INVALIDATED) { + he = he.getParent(); + if (he == null) { + // root reached without intermediate invalidated entry + return; + } + } + // he is INVALIDATED -> force reloading in order to be aware of id changes + he.getItemState(); + } } Added: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/IsSameTest.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/IsSameTest.java?rev=706273&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/IsSameTest.java (added) +++ jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/IsSameTest.java Mon Oct 20 06:16:49 2008 @@ -0,0 +1,392 @@ +/* + * 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; + +import org.apache.jackrabbit.test.AbstractJCRTest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jcr.InvalidItemStateException; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import java.util.Calendar; + +/** IsSameTest... */ +public class IsSameTest extends AbstractJCRTest { + + private static Logger log = LoggerFactory.getLogger(IsSameTest.class); + + public void testIsSameProperty() throws RepositoryException { + + Node n = testRootNode.addNode(nodeName1, testNodeType); + Property p = n.setProperty(propertyName1, "anyvalue"); + testRootNode.save(); + + // access same property through different session + Session otherSession = helper.getReadOnlySession(); + try { + Property otherProperty = (Property) otherSession.getItem(p.getPath()); + assertTrue(p.isSame(otherProperty)); + } finally { + otherSession.logout(); + } + } + + public void testIsSameProperty2() throws RepositoryException { + + Node n = testRootNode.addNode(nodeName1, testNodeType); + Property p = n.setProperty(propertyName1, "anyvalue"); + testRootNode.save(); + + // add transient modification to the property: + p.setValue("someOtherValue"); + + // access same property through different session + Session otherSession = helper.getReadOnlySession(); + try { + Property otherProperty = (Property) otherSession.getItem(p.getPath()); + assertTrue(p.isSame(otherProperty)); + } finally { + otherSession.logout(); + } + } + + public void testIsSameProperty3() throws RepositoryException { + // create a node (nt:resource) that implicitely is referenceable + Node n = testRootNode.addNode("aFile", "nt:file"); + n = n.addNode("jcr:content", "nt:resource"); + n.setProperty("jcr:lastModified", Calendar.getInstance()); + n.setProperty("jcr:mimeType", "text/plain"); + Property jcrData = n.setProperty("jcr:data", "abc", PropertyType.BINARY); + testRootNode.save(); + + // access same property through different session + Session otherSession = helper.getReadOnlySession(); + try { + Property otherProperty = (Property) otherSession.getItem(jcrData.getPath()); + assertTrue(jcrData.isSame(otherProperty)); + } finally { + otherSession.logout(); + } + } + + public void testIsSameProperty4() throws RepositoryException { + // create a node (nt:resource) that implicitely is referenceable + Node n = testRootNode.addNode("aFile", "nt:file"); + n = n.addNode("jcr:content", "nt:resource"); + n.setProperty("jcr:lastModified", Calendar.getInstance()); + n.setProperty("jcr:mimeType", "text/plain"); + Property jcrData = n.setProperty("jcr:data", "abc", PropertyType.BINARY); + testRootNode.save(); + + // access same property through different session + Session otherSession = helper.getReadOnlySession(); + try { + Property otherProperty = (Property) otherSession.getItem(jcrData.getPath()); + assertTrue(n.getProperty("jcr:data").isSame(otherProperty)); + } finally { + otherSession.logout(); + } + } + + public void testIsSameNode() throws RepositoryException { + // create a node (nt:resource) that implicitely is referenceable + Node n = testRootNode.addNode("aFile", "nt:file"); + n = n.addNode("jcr:content", "nt:resource"); + n.setProperty("jcr:lastModified", Calendar.getInstance()); + n.setProperty("jcr:mimeType", "text/plain"); + n.setProperty("jcr:data", "abc", PropertyType.BINARY); + testRootNode.save(); + + // access nt:resource node through different session + Session otherSession = helper.getReadOnlySession(); + try { + Node otherNode = (Node) otherSession.getItem(n.getPath()); + assertTrue(n.isSame(otherNode)); + } finally { + otherSession.logout(); + } + } + + public void testIsSameNode2() throws RepositoryException { + // create a node (nt:resource) that implicitely is referenceable + Node n = testRootNode.addNode("aFile", "nt:file"); + n = n.addNode("jcr:content", "nt:resource"); + n.setProperty("jcr:lastModified", Calendar.getInstance()); + n.setProperty("jcr:mimeType", "text/plain"); + n.setProperty("jcr:data", "abc", PropertyType.BINARY); + testRootNode.save(); + + // access nt:resource node through different session + Session otherSession = helper.getReadOnlySession(); + try { + Node otherNode = (Node) otherSession.getItem(n.getPath()); + assertTrue(otherNode.isSame(n)); + } finally { + otherSession.logout(); + } + } + + public void testIsSameNode3() throws RepositoryException { + + Node n = testRootNode.addNode(nodeName1, testNodeType); + Property p = n.setProperty(propertyName1, "anyvalue"); + testRootNode.save(); + + String srcPath = n.getPath(); + String destPath = testRootNode.getPath() + "/" + nodeName2; + + // transiently move the node. + testRootNode.getSession().move(srcPath, destPath); + assertTrue(n.isSame(superuser.getItem(destPath))); + } + + public void testIsSameNode4() throws RepositoryException { + + Node n = testRootNode.addNode(nodeName1, testNodeType); + Property p = n.setProperty(propertyName1, "anyvalue"); + testRootNode.save(); + + // transiently move the node. + String srcPath = n.getPath(); + String destPath = testRootNode.getPath() + "/" + nodeName2; + testRootNode.getSession().move(srcPath, destPath); + + Session otherSession = helper.getReadOnlySession(); + try { + Node otherNode = (Node) otherSession.getItem(srcPath); + assertTrue(n.isSame(otherNode)); + assertTrue(superuser.getItem(destPath).isSame(otherNode)); + } finally { + otherSession.logout(); + } + } + + public void testIsSameNode5() throws RepositoryException { + + Node n = testRootNode.addNode(nodeName1, testNodeType); + n.addMixin(mixReferenceable); + testRootNode.save(); + + // transiently move the node. + String srcPath = n.getPath(); + String destPath = testRootNode.getPath() + "/" + nodeName2; + + Session otherSession = helper.getReadOnlySession(); + try { + Node otherNode = (Node) otherSession.getItem(srcPath); + + testRootNode.getSession().getWorkspace().move(srcPath, destPath); + + assertTrue(otherNode.isSame(n)); + assertTrue(n.isSame(otherNode)); + } finally { + otherSession.logout(); + } + } + + public void testIsSameNode6() throws RepositoryException { + + Node n = testRootNode.addNode(nodeName1, testNodeType); + n.addMixin(mixReferenceable); + testRootNode.save(); + + // transiently move the node. + String srcPath = n.getPath(); + String destPath = testRootNode.getPath() + "/" + nodeName2; + + Session otherSession = helper.getReadOnlySession(); + try { + Node otherNode = (Node) otherSession.getItem(srcPath); + + testRootNode.getSession().getWorkspace().move(srcPath, destPath); + + otherNode.refresh(false); + try { + assertTrue(n.isSame(otherNode)); + } catch (InvalidItemStateException e) { + // ok as well. + } + try { + assertTrue(otherNode.isSame(n)); + } catch (InvalidItemStateException e) { + // ok as well. + } + } finally { + otherSession.logout(); + } + } + + public void testIsSameNode7() throws RepositoryException { + + Node n = testRootNode.addNode(nodeName1, testNodeType); + Node n2 = n.addNode(nodeName2); + Node n3 = n2.addNode(nodeName3); + testRootNode.save(); + + n.addMixin(mixReferenceable); + testRootNode.save(); + + Session otherSession = helper.getReadOnlySession(); + try { + Node otherNode3 = (Node) otherSession.getItem(n3.getPath()); + + assertTrue(otherNode3.isSame(n3)); + Node parent = otherNode3.getParent(); + assertTrue(parent.isSame(n2)); + parent = parent.getParent(); + assertTrue(parent.isSame(n)); + parent = parent.getParent(); + assertTrue(testRootNode.isSame(parent)); + } finally { + otherSession.logout(); + } + } + + public void testSameInstanceIsSame() throws RepositoryException { + assertTrue(testRootNode.isSame(testRootNode)); + + Property p = testRootNode.getProperty(jcrPrimaryType); + assertTrue(p.isSame(p)); + } + + public void testNewNodeIsSame() throws RepositoryException { + Node n = testRootNode.addNode(nodeName1, testNodeType); + assertTrue(n.isSame(n)); + + n.remove(); + Node n2 = testRootNode.addNode(nodeName1, testNodeType); + + try { + assertFalse(n2.isSame(n)); + } catch (InvalidItemStateException e) { + // ok as well + } + try { + assertFalse(n.isSame(n2)); + } catch (InvalidItemStateException e) { + // ok as well + } + } + + public void testNewPropertyIsSame() throws RepositoryException { + Node n = testRootNode.addNode(nodeName1, testNodeType); + Property p = n.setProperty(propertyName1, "anyValue"); + + assertTrue(p.isSame(p)); + } + + public void testNewItemFromDifferentSessions() throws RepositoryException { + Node n = testRootNode.addNode(nodeName1, testNodeType); + Property p = n.setProperty(propertyName1, "anyValue"); + + Session s2 = helper.getReadWriteSession(); + try { + Node trn = (Node) s2.getItem(testRootNode.getPath()); + Node n2 = trn.addNode(nodeName1, testNodeType); + Property p2 = n2.setProperty(propertyName1, "anyValue"); + + assertFalse(n.isSame(n2)); + assertFalse(n2.isSame(n)); + assertFalse(p.isSame(p2)); + assertFalse(p2.isSame(p)); + } finally { + s2.logout(); + } + } + + public void testDifferentItemType() throws RepositoryException { + Node n = testRootNode.addNode(nodeName1, testNodeType); + Property p = n.setProperty(propertyName1, "anyValue"); + + assertFalse(p.isSame(n)); + assertFalse(n.isSame(p)); + } + + public void testShadowingItems() throws RepositoryException { + Node n = testRootNode.addNode(nodeName1, testNodeType); + Node n2 = testRootNode.addNode(nodeName2, testNodeType); + + Property p = n.setProperty(propertyName1, "anyValue"); + testRootNode.save(); + + testRootNode.getSession().move(n.getPath(), n2.getPath() + "/destination"); + + Node replaceNode = testRootNode.addNode(nodeName1, testNodeType); + Property replaceProp = replaceNode.setProperty(propertyName1, "anyValue"); + + assertFalse(replaceNode.isSame(n)); + assertFalse(replaceProp.isSame(p)); + } + + public void testShadowingItems2() throws RepositoryException { + Node n = testRootNode.addNode(nodeName1, testNodeType); + Node n2 = testRootNode.addNode(nodeName2, testNodeType); + Property p = n.setProperty(propertyName1, "anyValue"); + + testRootNode.getSession().move(n.getPath(), n2.getPath() + "/destination"); + + Node replaceNode = testRootNode.addNode(nodeName1, testNodeType); + Property replaceProp = replaceNode.setProperty(propertyName1, "anyValue"); + + assertFalse(replaceNode.isSame(n)); + assertFalse(replaceProp.isSame(p)); + } + + public void testShadowingItems3() throws RepositoryException { + Node n = testRootNode.addNode(nodeName1, testNodeType); + Property p = n.setProperty(propertyName1, "anyValue"); + testRootNode.save(); + + p.remove(); + Property p2 = n.setProperty(propertyName1, "anyValue"); + try { + assertFalse(p2.isSame(p)); + } catch (InvalidItemStateException e) { + // ok as well. + } + } + + /** + * 283 specific test where node and prop with same name can be siblings. + * + * @throws RepositoryException + */ + /* + public void testIsSameDifferentItemType() throws RepositoryException { + Node n = testRootNode.addNode(nodeName1, testNodeType); + testRootNode.save(); + + Session s2 = helper.getReadWriteSession(); + try { + Node trn = (Node) s2.getItem(testRootNode.getPath()); + Property p = trn.setProperty(nodeName1, "anyValue"); + trn.save(); + + assertFalse(n.isSame(p)); + + } finally { + s2.logout(); + } + } + */ + + +} \ No newline at end of file Propchange: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/IsSameTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/IsSameTest.java ------------------------------------------------------------------------------ svn:keywords = author date id revision url 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=706273&r1=706272&r2=706273&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 Mon Oct 20 06:16:49 2008 @@ -94,6 +94,7 @@ suite.addTestSuite(HierarchyNodeTest.class); suite.addTestSuite(LazyItemIteratorTest.class); suite.addTestSuite(ExternalModificationTest.class); + suite.addTestSuite(IsSameTest.class); return suite; }