You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2005/02/15 14:56:51 UTC
svn commit: r153936 - in incubator/jackrabbit/trunk: applications/test/
src/test/org/apache/jackrabbit/init/ src/test/org/apache/jackrabbit/test/
src/test/org/apache/jackrabbit/test/api/
Author: mreutegg
Date: Tue Feb 15 05:56:44 2005
New Revision: 153936
URL: http://svn.apache.org/viewcvs?view=rev&rev=153936
Log:
Adding more test cases for package javax.jcr.
Added:
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/NodeTestData.java (with props)
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemDefTest.java (with props)
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemReadMethodsTest.java (with props)
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/NodeReadMethodsTest.java (with props)
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/PropertyTypeTest.java (with props)
Modified:
incubator/jackrabbit/trunk/applications/test/repositoryStubImpl.properties
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/TestAll.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/AbstractJCRTest.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/TestAll.java
Modified: incubator/jackrabbit/trunk/applications/test/repositoryStubImpl.properties
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/applications/test/repositoryStubImpl.properties?view=diff&r1=153935&r2=153936
==============================================================================
--- incubator/jackrabbit/trunk/applications/test/repositoryStubImpl.properties (original)
+++ incubator/jackrabbit/trunk/applications/test/repositoryStubImpl.properties Tue Feb 15 05:56:44 2005
@@ -5,6 +5,11 @@
# Stub implementation class
javax.jcr.tck.repository_stub_impl=org.apache.jackrabbit.test.JackrabbitRepositoryStub
+# repository name
+org.apache.jackrabbit.repository.config=applications/test/repository.xml
+org.apache.jackrabbit.repository.name=repo
+org.apache.jackrabbit.repository.home=applications/test
+
# credential configuration
javax.jcr.tck.superuser.name=superuser
javax.jcr.tck.superuser.pwd=
@@ -33,7 +38,25 @@
# Test method: testName
javax.jcr.tck.AddNodeTest.testName.nodename1=myname
-# QUERY CONFIGURATION
+# ==============================================================================
+# JAVAX.JCR CONFIGURATION
+# ==============================================================================
+
+# Test class: ItemDefTest
+javax.jcr.tck.ItemDefTest.testroot=/
+
+# Test class: ItemReadMethodsTest
+javax.jcr.tck.ItemReadMethodsTest.testroot=/
+
+# Test class: NodeReadMethodsTest
+javax.jcr.tck.NodeReadMethodsTest.testroot=/
+
+# Test class: PropertyTypeTest
+javax.jcr.tck.PropertyTypeTest.testroot=/
+
+# ==============================================================================
+# JAVAX.JCR.QUERY CONFIGURATION
+# ==============================================================================
# Test class: SaveTest
# Test method: testConstraintViolationException
@@ -64,7 +87,9 @@
# Test class: SQLOrderByTest
javax.jcr.tck.SQLOrderByTest.testroot=/testdata/query
-# VERSIONING CONFIGURATION
+# ==============================================================================
+# JAVAX.JCR.VERSIONING CONFIGURATION
+# ==============================================================================
# nodetye that is versionable. if it is not, an attempt is made to create versionable nodes
# by adding a mix:versionable mixin-type.
@@ -116,8 +141,3 @@
# Test class: MergeNodeTest
javax.jcr.tck.MergeNodeTest.nodetype=test:versionable
-
-# repository name
-org.apache.jackrabbit.repository.config=applications/test/repository.xml
-org.apache.jackrabbit.repository.name=repo
-org.apache.jackrabbit.repository.home=applications/test
Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/NodeTestData.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/NodeTestData.java?view=auto&rev=153936
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/NodeTestData.java (added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/NodeTestData.java Tue Feb 15 05:56:44 2005
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.init;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Node;
+import java.util.StringTokenizer;
+import java.util.Calendar;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * Sets up test data required for level 1 node test cases.
+ */
+public class NodeTestData extends AbstractJCRTest {
+
+ /** Path pointing to the test root */
+ private static final String TEST_DATA_PATH = "testdata/node";
+
+ /** Resolved QName for nt:resource */
+ private String ntResource;
+
+ /** Resolved QName for jcr:encoding */
+ private String jcrEncoding;
+
+ /** Resolved QName for jcr:mimeType */
+ private String jcrMimeType;
+
+ /** Resolved QName for jcr:data */
+ private String jcrData;
+
+ /** Resolved QName for jcr:lastModified */
+ private String jcrLastModified;
+
+ /**
+ * Sets up the fixture for this test.
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ ntResource = superuser.getNamespacePrefix(NS_NT_URI) + ":resource";
+ jcrEncoding = superuser.getNamespacePrefix(NS_JCR_URI) + ":encoding";
+ jcrMimeType = superuser.getNamespacePrefix(NS_JCR_URI) + ":mimeType";
+ jcrData = superuser.getNamespacePrefix(NS_JCR_URI) + ":data";
+ jcrLastModified = superuser.getNamespacePrefix(NS_JCR_URI) + ":lastModified";
+ }
+
+ /**
+ * Creates two nodes under {@link #TEST_DATA_PATH}: one of type
+ * nt:resource and a second node referencing the first.
+ */
+ public void testFillInSearchData() throws RepositoryException, IOException {
+ if (superuser.getRootNode().hasNode(TEST_DATA_PATH)) {
+ // delete previous data
+ superuser.getRootNode().getNode(TEST_DATA_PATH).remove();
+ superuser.save();
+ }
+ // create nodes to testPath
+ StringTokenizer names = new StringTokenizer(TEST_DATA_PATH, "/");
+ Node dataRoot = superuser.getRootNode();
+ while (names.hasMoreTokens()) {
+ String name = names.nextToken();
+ if (!dataRoot.hasNode(name)) {
+ dataRoot = dataRoot.addNode(name, testNodeType);
+ } else {
+ dataRoot = dataRoot.getNode(name);
+ }
+ }
+
+ Node resource = dataRoot.addNode("myResource", ntResource);
+ resource.setProperty(jcrEncoding, "ISO-8859-1");
+ resource.setProperty(jcrMimeType, "text/plain");
+ ByteArrayOutputStream data = new ByteArrayOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(data, "ISO-8859-1");
+ writer.write("Hello world.");
+ writer.close();
+ resource.setProperty(jcrData, new ByteArrayInputStream(data.toByteArray()));
+ resource.setProperty(jcrLastModified, Calendar.getInstance());
+ log.println("Adding node: " + resource.getPath());
+
+ Node resReference = dataRoot.addNode("reference");
+ resReference.setProperty("ref", resource);
+ log.println("Adding node: " + resReference.getPath());
+
+ superuser.save();
+ }
+}
Propchange: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/NodeTestData.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/TestAll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/TestAll.java?view=diff&r1=153935&r2=153936
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/TestAll.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/init/TestAll.java Tue Feb 15 05:56:44 2005
@@ -38,6 +38,7 @@
TestSuite suite = new TestSuite("Setup data for tests");
suite.addTestSuite(QueryTestData.class);
+ suite.addTestSuite(NodeTestData.class);
return suite;
}
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/AbstractJCRTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/AbstractJCRTest.java?view=diff&r1=153935&r2=153936
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/AbstractJCRTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/AbstractJCRTest.java Tue Feb 15 05:56:44 2005
@@ -233,10 +233,14 @@
}
if (isReadOnly) {
- if (!superuser.getRootNode().hasNode(testPath)) {
+ if (testPath.length() == 0) {
+ // test root is the root node
+ testRootNode = superuser.getRootNode();
+ } else if (!superuser.getRootNode().hasNode(testPath)) {
fail("Workspace does not contain test data at: " + testRoot);
+ } else {
+ testRootNode = superuser.getRootNode().getNode(testPath);
}
- testRootNode = superuser.getRootNode().getNode(testPath);
} else {
Node root = superuser.getRootNode();
if (root.hasNode(testPath)) {
Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemDefTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemDefTest.java?view=auto&rev=153936
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemDefTest.java (added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemDefTest.java Tue Feb 15 05:56:44 2005
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.test.api;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.Session;
+import javax.jcr.RepositoryException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.PropertyDef;
+import javax.jcr.nodetype.NodeDef;
+
+/**
+ * This test checks if item definitions with mandatory constraints are
+ * respected.
+ * <p/>
+ * If the default workspace does not contain a node with a node type definition
+ * that specifies a mandatory child node a {@link NotExecutableException} is
+ * thrown. If the default workspace does not contain a node with a node type
+ * definition that specifies a mandatory property a {@link NotExecutableException}
+ * is thrown.
+ *
+ * @test
+ * @sources ItemDefTest.java
+ * @executeClass org.apache.jackrabbit.test.api.ItemDefTest
+ * @keywords level1
+ */
+public class ItemDefTest extends AbstractJCRTest {
+
+ /** If <code>true</code> indicates that the test found a mandatory node */
+ private boolean foundMandatoryNode = false;
+
+ /** If <code>true</code> indicates that the test found a mandatory property */
+ private boolean foundMandatoryProperty = false;
+
+ /**
+ * Sets up the fixture for this test.
+ */
+ protected void setUp() throws Exception {
+ isReadOnly = true;
+ super.setUp();
+ }
+
+ /**
+ * Tests if a node's mandatory properties and nodes are legally set. The
+ * information which properties and nodes are mandatory is taken from the
+ * node's primary and mixin node types. This test runs recursively through
+ * the entire repository.
+ */
+ public void testIsMandatory() throws RepositoryException, NotExecutableException {
+ //Session session=superuser;
+ Session session = helper.getReadOnlySession();
+ Node root = session.getRootNode();
+ traverse(root);
+ if (!foundMandatoryNode) {
+ throw new NotExecutableException("Workspace does not contain any node with a mandatory child node definition");
+ }
+ if (!foundMandatoryProperty) {
+ throw new NotExecutableException("Workspace does not contain any node with a mandatory property definition");
+ }
+ }
+
+ /**
+ * Traverses the node hierarchy and applies {@link #checkMandatoryConstraint(javax.jcr.Node, javax.jcr.nodetype.NodeType)}
+ * to all descendant nodes of <code>parentNode</code>.
+ */
+ private void traverse(Node parentNode)
+ throws RepositoryException {
+
+ NodeIterator nodes = parentNode.getNodes();
+ while (nodes.hasNext()) {
+ Node node = nodes.nextNode();
+
+ NodeType primeType = node.getPrimaryNodeType();
+ checkMandatoryConstraint(node, primeType);
+
+ NodeType mixins[] = node.getMixinNodeTypes();
+ for (int i = 0; i < mixins.length; i++) {
+ checkMandatoryConstraint(node, mixins[i]);
+ }
+
+ traverse(node);
+ }
+ }
+
+ /**
+ * Checks if mandatory node / property definitions are respected.
+ */
+ private void checkMandatoryConstraint(Node node, NodeType type)
+ throws RepositoryException {
+
+ // test if node contains all mandatory properties of current type
+ PropertyDef propDefs[] = type.getPropertyDefs();
+ for (int i = 0; i < propDefs.length; i++) {
+ PropertyDef propDef = propDefs[i];
+
+ if (propDef.isMandatory()) {
+ foundMandatoryProperty = true;
+ String name = propDef.getName();
+
+ try {
+ Property p = node.getProperty(name);
+ if (propDef.isMultiple()) {
+ // empty array fails
+ assertFalse("A mandatory and multiple property " +
+ "must not be empty.",
+ p.getValues().length == 0);
+ } else {
+ // empty value fails
+ assertNotNull("A mandatory property must have a value",
+ p.getValue());
+ }
+ } catch (PathNotFoundException e) {
+ fail("Mandatory property " + name + " does not exist.");
+ }
+ }
+ }
+
+ // test if node contains all mandatory nodes of current type
+ NodeDef nodeDefs[] = type.getChildNodeDefs();
+ for (int i = 0; i < nodeDefs.length; i++) {
+ NodeDef nodeDef = nodeDefs[i];
+ if (nodeDef.isMandatory()) {
+ foundMandatoryNode = true;
+ try {
+ node.getNode(nodeDef.getName());
+ } catch (PathNotFoundException e) {
+ fail("Mandatory child " + nodeDef.getName() + " for " + node.getPath() + " does not exist.");
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemDefTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemReadMethodsTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemReadMethodsTest.java?view=auto&rev=153936
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemReadMethodsTest.java (added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemReadMethodsTest.java Tue Feb 15 05:56:44 2005
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.test.api;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.Session;
+import javax.jcr.Item;
+import javax.jcr.Property;
+import javax.jcr.NodeIterator;
+import javax.jcr.Node;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.ItemNotFoundException;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests the 'read' methods specified in the {@link javax.jcr.Item} interface
+ * on a level 1 repository.
+ * <p/>
+ * The root node of the default workspace must have at least one child node,
+ * otherwise a {@link org.apache.jackrabbit.test.NotExecutableException} is
+ * thrown.
+ *
+ * @test
+ * @sources ItemReadMethodsTest.java
+ * @executeClass org.apache.jackrabbit.test.api.ItemReadMethodsTest
+ * @keywords level1
+ */
+public class ItemReadMethodsTest extends AbstractJCRTest {
+
+ /** Session to access the workspace */
+ private Session session;
+
+ /** The primary test item */
+ private Item item;
+
+ /** A child item of the primary test item */
+ private Item childItem;
+
+ /** A property of the primary test item */
+ private Property childProperty;
+
+ /**
+ * Sets up the fixture for this test.
+ */
+ protected void setUp() throws Exception {
+ isReadOnly = true;
+ super.setUp();
+
+ session = helper.getReadOnlySession();
+ item = session.getRootNode();
+
+ NodeIterator nodes = ((Node) item).getNodes();
+ try {
+ childItem = nodes.nextNode();
+ } catch (NoSuchElementException e) {
+ throw new NotExecutableException("Workspace does not have sufficient content to run this test.");
+ }
+
+ PropertyIterator properties = ((Node) item).getProperties();
+ try {
+ childProperty = properties.nextProperty();
+ } catch (NoSuchElementException e) {
+ fail("Any node must have at least one property set: jcr:primaryType");
+ }
+ }
+
+ /**
+ * Tests if getPath() returns the correct path.
+ */
+ public void testGetPath() throws RepositoryException {
+ String path = childItem.getPath();
+ String notation = "";
+
+ try {
+ // check for same named sibling of childItem
+ ((Node) item).getNode(childItem.getName() + "[2]");
+ notation = "[1]";
+ } catch (PathNotFoundException e) {
+ }
+
+ if (path.indexOf("[") != -1) {
+ notation = path.substring(path.indexOf("["));
+ }
+ assertEquals("getPath returns wrong result",
+ "/" + childItem.getName() + notation,
+ childItem.getPath());
+ }
+
+ /**
+ * Tests if getName() returns same as last name returned by getPath()
+ */
+ public void testGetName() throws RepositoryException {
+ assertEquals("getName() of root must be an empty string",
+ "",
+ item.getName());
+
+ // build name from path
+ String path = childItem.getPath();
+ String name = path.substring(path.lastIndexOf("/") + 1);
+ if (name.indexOf("[") != -1) {
+ name = name.substring(0, name.indexOf("["));
+ }
+ assertEquals("getName() must be the same as the last item in the path",
+ name,
+ childItem.getName());
+ }
+
+ /**
+ * Tests if getItem(x).getParent() is item itself
+ */
+ public void testGetParent() throws RepositoryException {
+ assertSame("getParent() of a child item must be the item itself.",
+ item, childItem.getParent());
+ }
+
+ /**
+ * Tests if getParent() of root throws an ItemNotFoundException
+ */
+ public void testGetParentOfRoot() throws RepositoryException {
+ try {
+ item.getParent();
+ fail("getParent() of root must throw an ItemNotFoundException.");
+ } catch (ItemNotFoundException e) {
+ // success
+ }
+ }
+
+ /**
+ * Tests if depth of root is 0 and depth of a sub item of root is 1
+ */
+ public void testGetDepth() throws RepositoryException {
+ assertEquals("getDepth() of root must be 0", 0, item.getDepth());
+ assertEquals("getDepth() of child item of root must be 1", 1,
+ childItem.getDepth());
+ }
+
+ /**
+ * Tests if getSession() is same as through which the Item was acquired
+ */
+ public void testGetSession() throws RepositoryException {
+ assertSame("getSession must return the Session through which " +
+ "the Item was acquired.",
+ item.getSession(),
+ session);
+ }
+
+ /**
+ * Tests if isNode() returns true if the Item is a node and false if it is a
+ * property
+ */
+ public void testIsNode() {
+ assertTrue("isNode() must return true if Item is a node.",
+ childItem.isNode());
+ assertFalse("isNode() must return false if Item is a property.",
+ childProperty.isNode());
+ }
+
+ /**
+ * Tests if isSame() returns true when retrieving an item through different
+ * sessions
+ */
+ public void testIsSame() throws RepositoryException {
+ assertFalse("isSame(Item item) must return false for different items.",
+ item.isSame(childItem));
+
+ // access same item (root) through different session
+ Item otherItem = helper.getReadOnlySession().getRootNode();
+ assertTrue("isSame(Item item) must return true for the same " +
+ "item retrieved through different sessions.",
+ item.isSame(otherItem));
+ }
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/ItemReadMethodsTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/NodeReadMethodsTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/NodeReadMethodsTest.java?view=auto&rev=153936
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/NodeReadMethodsTest.java (added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/NodeReadMethodsTest.java Tue Feb 15 05:56:44 2005
@@ -0,0 +1,832 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.test.api;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+import javax.jcr.RepositoryException;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Property;
+import javax.jcr.Item;
+import javax.jcr.PropertyType;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.ItemNotFoundException;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests the 'read' methods specified in the {@link javax.jcr.Node} interface
+ * on a level 1 repository.
+ * <p/>
+ * Most tests require at least one child node under the root node, otherwise
+ * a {@link org.apache.jackrabbit.test.NotExecutableException} is thrown.
+ *
+ * @test
+ * @sources NodeReadMethodsTest.java
+ * @executeClass org.apache.jackrabbit.test.api.NodeReadMethodsTest
+ * @keywords level1
+ */
+public class NodeReadMethodsTest extends AbstractJCRTest {
+
+ /**
+ * The root node of the default workspace
+ */
+ Node rootNode;
+
+ /**
+ * Sets up the fixture for this test.
+ */
+ protected void setUp() throws Exception {
+ isReadOnly = true;
+ super.setUp();
+ Session session = helper.getReadOnlySession();
+ rootNode = session.getRootNode();
+ }
+
+ /**
+ * Test if getNode(String relPath) returns the correct node and if a
+ * PathNotFoundException is thrown when Node at relPath does not exist
+ */
+ public void testGetNode()
+ throws NotExecutableException, RepositoryException {
+
+ StringBuffer notExistingPath = new StringBuffer("X");
+ NodeIterator nodes = rootNode.getNodes();
+ while (nodes.hasNext()) {
+ // build a path that for sure is not existing
+ // (":" of namespace prefix will be replaced later on)
+ notExistingPath.append(nodes.nextNode().getName());
+ }
+
+ try {
+ rootNode.getNode(notExistingPath.toString().replaceAll(":", ""));
+ fail("getNode(String relPath) must throw a PathNotFoundException" +
+ "if no node exists at relPath");
+ } catch (PathNotFoundException e) {
+ // success
+ }
+
+ try {
+ NodeIterator nodes2 = rootNode.getNodes();
+ Node node = nodes2.nextNode();
+ assertSame(rootNode.getNode(node.getName()), node);
+ } catch (NoSuchElementException e) {
+ throw new NotExecutableException("Workspace does not have sufficient content for this test. Root node must have at least one child node.");
+ }
+ }
+
+ /**
+ * Test if all returned items are of type node.
+ */
+ public void testGetNodes() throws RepositoryException {
+ NodeIterator nodes = rootNode.getNodes();
+ while (nodes.hasNext()) {
+ Item item = (Item) nodes.next();
+ assertTrue("Item is not a node", item.isNode());
+ }
+ }
+
+ /**
+ * Test getNodes(String namePattern) with all possible patterns. Tested
+ * node: root - NotExecutableException is thrown when root node has no sub
+ * nodes.
+ */
+ public void testGetNodesNamePattern()
+ throws NotExecutableException, RepositoryException {
+
+ // get root node and build an ArrayList of its sub nodes
+ Node node = rootNode;
+ if (!node.hasNodes()) {
+ throw new NotExecutableException("Workspace does not have sufficient content for this test. Root node must have at least one child node.");
+ }
+ NodeIterator allNodesIt = node.getNodes();
+ ArrayList allNodes = new ArrayList();
+ while (allNodesIt.hasNext()) {
+ Node n = allNodesIt.nextNode();
+ allNodes.add(n);
+ }
+
+
+ // test if an empty NodeIterator is returned
+ // when the pattern is not matching any child node
+ String pattern0 = "";
+ NodeIterator nodes0 = node.getNodes(pattern0);
+ try {
+ nodes0.nextNode();
+ fail("An empty NodeIterator must be returned if pattern does" +
+ "not match any child node.");
+ } catch (NoSuchElementException e) {
+ // success
+ }
+
+
+ // all further tests are using root's first sub node
+ Node firstNode = (Node) allNodes.get(0);
+
+
+ // test pattern "*"
+ String pattern1 = "*";
+ String assertString1 = "node.getNodes(\"" + pattern1 + "\"): ";
+ NodeIterator nodes1 = node.getNodes(pattern1);
+ int numOfNodes1 = 0;
+ // test if the number of found nodes is correct
+ while (nodes1.hasNext()) {
+ nodes1.nextNode();
+ numOfNodes1++;
+ }
+ assertEquals(assertString1 + "number of nodes found: ",
+ allNodes.size(),
+ numOfNodes1);
+
+
+ // test pattern "nodeName"
+ String pattern2 = firstNode.getName();
+ String assertString2 = "node.getNodes(\"" + pattern2 + "\"): ";
+ int numOfNodes2 = 0;
+ // test if the names of the found nodes are matching the pattern
+ NodeIterator nodes2 = node.getNodes(pattern2);
+ while (nodes2.hasNext()) {
+ Node n = nodes2.nextNode();
+ assertEquals(assertString2 + "name comparison failed: ",
+ firstNode.getName(),
+ n.getName());
+ numOfNodes2++;
+ }
+ // test if the number of found nodes is correct
+ int numExpected2 = 0;
+ for (int i = 0; i < allNodes.size(); i++) {
+ Node n = (Node) allNodes.get(i);
+ if (n.getName().equals(firstNode.getName())) {
+ numExpected2++;
+ }
+ }
+ assertEquals(assertString2 + "number of nodes found: ",
+ numExpected2,
+ numOfNodes2);
+
+
+ // test pattern "nodeName | nodeName"
+ String pattern3 = firstNode.getName() + " | " + firstNode.getName();
+ String assertString3 = "node.getNodes(\"" + pattern3 + "\"): ";
+ int numOfNodes3 = 0;
+ // test if the names of the found nodes are matching the pattern
+ NodeIterator nodes3 = node.getNodes(pattern3);
+ while (nodes3.hasNext()) {
+ Node n = nodes3.nextNode();
+ assertEquals(assertString2 + "name comparison failed: ",
+ firstNode.getName(),
+ n.getName());
+ numOfNodes3++;
+ }
+ // test if the number of found nodes is correct
+ int numExpected3 = 0;
+ for (int i = 0; i < allNodes.size(); i++) {
+ Node n = (Node) allNodes.get(i);
+ if (n.getName().equals(firstNode.getName())) {
+ numExpected3++;
+ }
+ }
+ assertEquals(assertString3 + "number of nodes found: ",
+ numExpected3,
+ numOfNodes3);
+
+
+ // test pattern "*odeNam*"
+ if (firstNode.getName().length() > 2) {
+ String name = firstNode.getName();
+ String shortenName = name.substring(1, name.length() - 1);
+ String pattern4 = "*" + shortenName + "*";
+ String assertString4 = "node.getNodes(\"" + pattern4 + "\"): ";
+ int numOfNodes4 = 0;
+ // test if the names of the found nodes are matching the pattern
+ NodeIterator nodes4 = node.getNodes(pattern4);
+ while (nodes4.hasNext()) {
+ Node n = nodes4.nextNode();
+ assertTrue(assertString4 + "name comparison failed: *" +
+ shortenName + "* not found in " + n.getName(),
+ n.getName().indexOf(shortenName) != -1);
+ numOfNodes4++;
+ }
+ // test if the number of found nodes is correct
+ int numExpected4 = 0;
+ for (int i = 0; i < allNodes.size(); i++) {
+ Node n = (Node) allNodes.get(i);
+ if (n.getName().indexOf(shortenName) != -1) {
+ numExpected4++;
+ }
+ }
+ assertEquals(assertString4 + "number of nodes found: ",
+ numExpected4,
+ numOfNodes4);
+ }
+ }
+
+ /**
+ * Test if getProperty(String relPath) returns the correct node and if a
+ * PathNotFoundException is thrown when property at relPath does not exist
+ */
+ public void testGetProperty()
+ throws NotExecutableException, RepositoryException {
+ StringBuffer notExistingPath = new StringBuffer("X");
+ PropertyIterator properties = rootNode.getProperties();
+ while (properties.hasNext()) {
+ // build a path that for sure is not existing
+ // (":" of namespace prefix will be replaced later on)
+ notExistingPath.append(properties.nextProperty().getName());
+ }
+
+ try {
+ rootNode.getProperty(notExistingPath.toString().replaceAll(":", ""));
+ fail("getProperty(String relPath) must throw a " +
+ "PathNotFoundException if no node exists at relPath");
+ } catch (PathNotFoundException e) {
+ // success
+ }
+
+ try {
+ PropertyIterator properties2 = rootNode.getProperties();
+ Property property = properties2.nextProperty();
+ assertSame(rootNode.getProperty(property.getName()), property);
+ } catch (NoSuchElementException e) {
+ fail("Root node must always have at least one property: jcr:primaryType");
+ }
+ }
+
+ /**
+ * Test if all returned items are of type node.
+ */
+ public void testGetProperties() throws RepositoryException {
+ PropertyIterator properties = rootNode.getProperties();
+ while (properties.hasNext()) {
+ Item item = (Item) properties.next();
+ assertFalse("Item is not a property", item.isNode());
+ }
+ }
+
+ /**
+ * Test getProperties(String namePattern) with all possible patterns. Tested
+ * node: root - a NotExecutableException is thrown when root node has no
+ * properties.
+ */
+ public void testGetPropertiesNamePattern()
+ throws NotExecutableException, RepositoryException {
+
+ // get root node and build an ArrayList of its sub nodes
+ Node node = rootNode;
+ if (!node.hasProperties()) {
+ fail("Root node must always have at least one property: jcr:primaryType");
+ }
+ PropertyIterator allPropertiesIt = node.getProperties();
+ ArrayList allProperties = new ArrayList();
+ StringBuffer notExistingPropertyName = new StringBuffer();
+ while (allPropertiesIt.hasNext()) {
+ Property p = allPropertiesIt.nextProperty();
+ allProperties.add(p);
+ notExistingPropertyName.append(p.getName() + "X");
+ }
+
+
+ // test that an empty NodeIterator is returned
+ // when the pattern is not matching any child node
+ String pattern0 = notExistingPropertyName.toString();
+ NodeIterator properties0 = node.getNodes(pattern0);
+ try {
+ properties0.nextNode();
+ fail("An empty NodeIterator must be returned if pattern does" +
+ "not match any child node.");
+ } catch (NoSuchElementException e) {
+ // success
+ }
+
+ // all tests are running using root's first property
+ Property firstProperty = (Property) allProperties.get(0);
+
+ // test: getProperties("*")
+ String pattern1 = "*";
+ String assertString1 = "node.getProperties(\"" + pattern1 + "\"): ";
+ PropertyIterator properties1 = node.getProperties(pattern1);
+ int numOfProperties1 = 0;
+ while (properties1.hasNext()) {
+ properties1.nextProperty();
+ numOfProperties1++;
+ }
+ assertEquals(assertString1 + "number of properties found: ",
+ allProperties.size(),
+ numOfProperties1);
+
+ // test: getProperties("propertyName")
+ String pattern2 = firstProperty.getName();
+ String assertString2 = "node.getProperties(\"" + pattern2 + "\"): ";
+ int numOfProperties2 = 0;
+ // test if the names of the found properties are matching the pattern
+ PropertyIterator properties2 = node.getProperties(pattern2);
+ while (properties2.hasNext()) {
+ Property p = properties2.nextProperty();
+ assertEquals(assertString2 + "name comparison failed: ",
+ firstProperty.getName(),
+ p.getName());
+ numOfProperties2++;
+ }
+ // test if the number of found properties is correct
+ int numExpected2 = 0;
+ for (int i = 0; i < allProperties.size(); i++) {
+ Property p = (Property) allProperties.get(i);
+ if (p.getName().equals(firstProperty.getName())) {
+ numExpected2++;
+ }
+ }
+ assertEquals(assertString2 + "number of properties found: ",
+ numExpected2,
+ numOfProperties2);
+
+
+ // test: getProperties("propertyName | propertyName")
+ String pattern3 = firstProperty.getName() + " | " + firstProperty.getName();
+ String assertString3 = "node.getProperties(\"" + pattern3 + "\"): ";
+ int numOfProperties3 = 0;
+ // test if the names of the found properties are matching the pattern
+ PropertyIterator properties3 = node.getProperties(pattern3);
+ while (properties3.hasNext()) {
+ Property p = properties3.nextProperty();
+ assertEquals(assertString2 + "name comparison failed: ",
+ firstProperty.getName(),
+ p.getName());
+ numOfProperties3++;
+ }
+ // test if the number of found properties is correct
+ int numExpected3 = 0;
+ for (int i = 0; i < allProperties.size(); i++) {
+ Property p = (Property) allProperties.get(i);
+ if (p.getName().equals(firstProperty.getName())) {
+ numExpected3++;
+ }
+ }
+ assertEquals(assertString3 + "number of properties found: ",
+ numExpected3,
+ numOfProperties3);
+
+
+ // test: getProperties("*opertyNam*")
+ if (firstProperty.getName().length() > 2) {
+ String name = firstProperty.getName();
+ String shortenName = name.substring(1, name.length() - 1);
+ String pattern4 = "*" + shortenName + "*";
+ String assertString4 = "node.getProperties(\"" + pattern4 + "\"): ";
+ int numOfProperties4 = 0;
+ // test if the names of the found properties are matching the pattern
+ PropertyIterator properties4 = node.getProperties(pattern4);
+ while (properties4.hasNext()) {
+ Property p = properties4.nextProperty();
+ assertTrue(assertString4 + "name comparison failed: *" +
+ shortenName + "* not found in " + p.getName(),
+ p.getName().indexOf(shortenName) != -1);
+ numOfProperties4++;
+ }
+ // test if the number of found properties is correct
+ int numExpected4 = 0;
+ for (int i = 0; i < allProperties.size(); i++) {
+ Property p = (Property) allProperties.get(i);
+ if (p.getName().indexOf(shortenName) != -1) {
+ numExpected4++;
+ }
+ }
+ assertEquals(assertString4 + "number of properties found: ",
+ numExpected4,
+ numOfProperties4);
+ }
+ }
+
+ /**
+ * Test if getPrimaryItem returns the primary item as defined in the primary
+ * node type. Therefor a node with a primary item is located recursively in
+ * the entire repository. A NotExecutableException is thrown when no such
+ * node is found.
+ */
+ public void testGetPrimaryItem()
+ throws NotExecutableException, RepositoryException {
+ Node node = locateNodeWithPrimaryItem(rootNode);
+ String primaryItemName = node.getPrimaryNodeType().getPrimaryItemName();
+
+ if (primaryItemName == null) {
+ throw new NotExecutableException("Workspace does not contain a node with primary item defined");
+ }
+
+ Item primaryItem = node.getPrimaryItem();
+ if (primaryItem.isNode()) {
+ assertSame(primaryItem, node.getNode(primaryItemName));
+ } else {
+ assertSame(primaryItem, node.getProperty(primaryItemName));
+ }
+ }
+
+ /**
+ * Test if getPrimaryItem does throw an ItemNotFoundException if the primary
+ * node type does not define a primary item. Therefor a node without a
+ * primary item is located recursively in the entire repository. A
+ * NotExecutableException is thrown when no such node is found.
+ */
+ public void testGetPrimaryItemItemNotFoundException()
+ throws NotExecutableException, RepositoryException {
+
+ Node node = locateNodeWithoutPrimaryItem(rootNode);
+
+ String primaryItemName = node.getPrimaryNodeType().getPrimaryItemName();
+
+ if (primaryItemName != null) {
+ throw new NotExecutableException("Workspace does not contain a node with primary item defined");
+ }
+
+ try {
+ node.getPrimaryItem();
+ fail("getPrimaryItem() must throw a ItemNotFoundException " +
+ "if the primary node type does not define one");
+ } catch (ItemNotFoundException e) {
+ // success
+ }
+ }
+
+ /**
+ * Test if getIndex() returns the correct index. Therefor a node with same
+ * name sibling is located recursively in the entire repository. If no such
+ * node is found, the test checks if the rootNode returns 1
+ */
+ public void testGetIndex()
+ throws RepositoryException {
+
+ Node node = locateNodeWithSameNameSiblings(rootNode);
+
+ if (node == rootNode) {
+ assertEquals("getIndex() of a node without same name siblings " +
+ "must return 1", node.getIndex(), 1);
+ } else {
+ NodeIterator nodes = node.getParent().getNodes(node.getName());
+ int i = 1;
+ while (nodes.hasNext()) {
+ assertEquals("getIndex() must return the correct index",
+ nodes.nextNode().getIndex(),
+ i);
+ i++;
+ }
+ }
+ }
+
+ public void testGetReferences()
+ throws NotExecutableException, RepositoryException {
+
+ Node node = locateNodeWithReference(rootNode);
+
+ if (node == rootNode) {
+ throw new NotExecutableException("Workspace does not contain a node with a reference property set");
+ }
+
+ PropertyIterator properties = node.getProperties();
+ while (properties.hasNext()) {
+ Property p = properties.nextProperty();
+ if (p.getType() == PropertyType.REFERENCE) {
+ Node referencedNode = p.getNode();
+ PropertyIterator refs = referencedNode.getReferences();
+ boolean referenceFound = false;
+ while (refs.hasNext()) {
+ if (refs.nextProperty() == p) {
+ referenceFound = true;
+ }
+ }
+ assertTrue("Correct reference not found", referenceFound);
+ }
+ }
+ }
+
+ /**
+ * Test if getUUID() returns the string value of the property "jcr:uuid".
+ * Therefor a node of type "mix:referenceable" is located recursively in the
+ * entire repository. A NotExecutableException is thrown when no node of
+ * this type is found.
+ *
+ * @throws NotExecutableException
+ * @throws RepositoryException
+ */
+ public void testGetUUID()
+ throws NotExecutableException, RepositoryException {
+
+ // find a node of type mix:referenceable
+ Node node = locateReferenceableNode(rootNode);
+
+ if (!node.isNodeType(mixReferenceable)) {
+ throw new NotExecutableException("Workspace does not contain a referencable node");
+ }
+
+ try {
+ assertEquals("node.getUUID() does not match " +
+ "node.getProperty(\"jcr:uuid\").getString()",
+ node.getProperty("jcr:uuid").getString(), node.getUUID());
+ } catch (PathNotFoundException e) {
+ fail("Property UUID expected for " +
+ "node of type \"" + mixReferenceable + "\"");
+ }
+ }
+
+ /**
+ * Test if getUUID() throws a UnsupportedRepositoryOperationException if
+ * Node is not referenceable
+ */
+ public void testGetUUIDOfNonReferenceableNode()
+ throws NotExecutableException, RepositoryException {
+
+ // find a node NOT of type mix:referenceable
+ Node node = locateNonReferenceableNode(rootNode);
+
+ if (node.isNodeType(mixReferenceable)) {
+ throw new NotExecutableException("Workspace does not contain a non referenceable node");
+ }
+
+ try {
+ node.getUUID();
+ fail("UnsupportedRepositoryOperationException expected");
+ } catch (UnsupportedRepositoryOperationException e) {
+ // success
+ }
+ }
+
+ /**
+ * Test if hasNode(String relPath) returns true if the required node exists
+ * and false if it doesn't. Tested node: root
+ */
+ public void testHasNode()
+ throws NotExecutableException, RepositoryException {
+
+ Node node = rootNode;
+
+ NodeIterator nodes = node.getNodes();
+ StringBuffer notExistingNodeName = new StringBuffer();
+ while (nodes.hasNext()) {
+ Node n = nodes.nextNode();
+ assertTrue("hasNode(String relPath) returns false although " +
+ "node at relPath is existing",
+ node.hasNode(n.getName()));
+ notExistingNodeName.append(n.getName() + "X");
+ }
+ if (notExistingNodeName.equals("")) {
+ throw new NotExecutableException("Workspace does not have sufficient content for this test. Root node must have at least one child node.");
+ }
+
+ assertFalse("hasNode(String relPath) returns true although " +
+ "node at relPath is not existing",
+ node.hasNode(notExistingNodeName.toString()));
+ }
+
+ /**
+ * Test if hasNodes() returns true if any sub node exists or false if not.
+ * Tested node: root
+ */
+ public void testHasNodes() throws RepositoryException {
+ Node node = rootNode;
+ NodeIterator nodes = node.getNodes();
+
+ int i = 0;
+ while (nodes.hasNext()) {
+ nodes.nextNode();
+ i++;
+ }
+
+ if (i == 0) {
+ assertFalse("node.hasNodes() returns true although " +
+ "no sub nodes existing",
+ node.hasNodes());
+ } else {
+ assertTrue("node.hasNodes() returns false althuogh " +
+ "sub nodes are existing",
+ node.hasNodes());
+ }
+ }
+
+ /**
+ * Test if hasProperty(String relPath) returns true if a required property
+ * exists and false if it doesn't. Tested node: root
+ */
+ public void testHasProperty()
+ throws NotExecutableException, RepositoryException {
+
+ Node node = rootNode;
+
+ PropertyIterator properties = node.getProperties();
+ StringBuffer notExistingPropertyName = new StringBuffer();
+ while (properties.hasNext()) {
+ Property p = properties.nextProperty();
+ assertTrue("node.hasProperty(\"relPath\") returns false " +
+ "although property at relPath is existing",
+ node.hasProperty(p.getName()));
+ notExistingPropertyName.append(p.getName() + "X");
+ }
+ if (notExistingPropertyName.equals("")) {
+ fail("Root node must at least have one property: jcr:primaryType");
+ }
+
+ assertFalse("node.hasProperty(\"relPath\") returns true " +
+ "although property at relPath is not existing",
+ node.hasProperty(notExistingPropertyName.toString()));
+ }
+
+ /**
+ * Test if hasProperty() returns true if any property exists or false if
+ * not. Tested node: root
+ *
+ * @throws RepositoryException
+ */
+ public void testHasProperties() throws RepositoryException {
+ Node node = rootNode;
+ PropertyIterator properties = node.getProperties();
+
+ int i = 0;
+ while (properties.hasNext()) {
+ Property p = properties.nextProperty();
+ log.println(p.getName());
+ i++;
+ }
+
+ if (i == 0) {
+ assertFalse("Must return false when no properties exist",
+ node.hasProperties());
+ } else {
+ assertTrue("Must return true when one or more properties exist",
+ node.hasProperties());
+ }
+ }
+
+ //-----------------------< internal >---------------------------------------
+
+ /**
+ * Returns the first descendant of <code>node</code> which is of type
+ * mix:referencable.
+ * @param node <code>Node</code> to start traversal.
+ * @return first node of type mix:referenceable
+ */
+ private Node locateReferenceableNode(Node node)
+ throws RepositoryException {
+
+ NodeIterator nodes = node.getNodes();
+ while (nodes.hasNext()) {
+ Node n = nodes.nextNode();
+ if (n.isNodeType(mixReferenceable)) {
+ return n;
+ } else {
+ Node returnedNode = locateReferenceableNode(n);
+ if (n != returnedNode) {
+ return returnedNode;
+ }
+ }
+ }
+ // no node of type "mix:referenceable" found - return passed node
+ return node;
+ }
+
+ /**
+ * Returns the first descendant of <code>node</code> which is not of
+ * type mix:referenceable.
+ * @param node <code>Node</code> to start traversal.
+ * @return first node which is not of type mix:referenceable
+ */
+ private Node locateNonReferenceableNode(Node node)
+ throws RepositoryException {
+
+ NodeIterator nodes = node.getNodes();
+ while (nodes.hasNext()) {
+ Node n = nodes.nextNode();
+ if (!n.isNodeType(mixReferenceable)) {
+ return n;
+ } else {
+ Node returnedNode = locateNonReferenceableNode(n);
+ if (n != returnedNode) {
+ return returnedNode;
+ }
+ }
+ }
+ // all nodes are of type "mix:referenceable" - return passed node
+ return node;
+ }
+
+ /**
+ * Returns the first descendant of <code>node</code> which has a property
+ * of type {@link javax.jcr.PropertyType#REFERENCE} set.
+ * @param node <code>Node</code> to start traversal.
+ * @return first node with a property of PropertType.REFERENCE
+ */
+ private Node locateNodeWithReference(Node node)
+ throws RepositoryException {
+ NodeIterator nodes = node.getNodes();
+ while (nodes.hasNext()) {
+ Node n = nodes.nextNode();
+ PropertyIterator properties = n.getProperties();
+ while (properties.hasNext()) {
+ Property p = properties.nextProperty();
+ if (p.getType() == PropertyType.REFERENCE) {
+ return n;
+ }
+ }
+
+ Node returnedNode = locateNodeWithReference(n);
+ if (n != returnedNode) {
+ return returnedNode;
+ }
+ }
+ // no node of type "mix:referenceable" found - return passed node
+ return node;
+ }
+
+ /**
+ * Returns the first descendant of <code>node</code> which defines a
+ * primary item.
+ * @param node <code>Node</code> to start traversal.
+ * @return first node with a primary item
+ */
+ private Node locateNodeWithPrimaryItem(Node node)
+ throws RepositoryException {
+ NodeIterator nodes = node.getNodes();
+ while (nodes.hasNext()) {
+ Node n = nodes.nextNode();
+ if (n.getPrimaryNodeType().getPrimaryItemName() != null) {
+ return n;
+ } else {
+ Node returnedNode = locateNodeWithPrimaryItem(n);
+ if (n != returnedNode) {
+ return returnedNode;
+ }
+ }
+ }
+ // no node with primary item found - return passed node
+ return node;
+ }
+
+ /**
+ * Returns the first descendant of <code>node</code> which does not define
+ * a primary item.
+ * @param node <code>Node</code> to start traversal.
+ * @return first node without a primary item
+ */
+ private Node locateNodeWithoutPrimaryItem(Node node)
+ throws RepositoryException {
+ NodeIterator nodes = node.getNodes();
+ while (nodes.hasNext()) {
+ Node n = nodes.nextNode();
+ if (n.getPrimaryNodeType().getPrimaryItemName() == null) {
+ return n;
+ } else {
+ Node returnedNode = locateNodeWithoutPrimaryItem(n);
+ if (n != returnedNode) {
+ return returnedNode;
+ }
+ }
+ }
+ // no node with primary item found - return passed node
+ return node;
+ }
+
+ /**
+ * Returns the first descendant of <code>node</code> which has same
+ * name siblings.
+ * @param node <code>Node</code> to start traversal.
+ * @return first node with same name siblings
+ */
+ private Node locateNodeWithSameNameSiblings(Node node)
+ throws RepositoryException {
+ NodeIterator nodes = node.getNodes();
+ while (nodes.hasNext()) {
+ Node n = nodes.nextNode();
+ NodeIterator nodes2 = node.getNodes(n.getName());
+ int i = 0;
+ while (nodes2.hasNext()) {
+ nodes2.next();
+ i++;
+ }
+ if (i > 1) {
+ // node has same name siblings
+ return n;
+ } else {
+ Node returnedNode = locateNodeWithSameNameSiblings(n);
+ if (n != returnedNode) {
+ return returnedNode;
+ }
+ }
+ }
+ // no node with same name siblings found - return passed node
+ return node;
+ }
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/NodeReadMethodsTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/PropertyTypeTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/PropertyTypeTest.java?view=auto&rev=153936
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/PropertyTypeTest.java (added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/PropertyTypeTest.java Tue Feb 15 05:56:44 2005
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.test.api;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.PropertyIterator;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+
+/**
+ * Tests if the type of a property is set according to the node type as well
+ * as no property is of type UNDEFINED. This test runs recursively through
+ * the entire repository.
+ *
+ * @test
+ * @sources PropertyTypeTest.java
+ * @executeClass org.apache.jackrabbit.test.api.PropertyTypeTest
+ * @keywords level1
+ */
+public class PropertyTypeTest extends AbstractJCRTest {
+
+ /**
+ * Sets up the fixture for this test.
+ */
+ protected void setUp() throws Exception {
+ isReadOnly = true;
+ super.setUp();
+ }
+
+ /**
+ * Tests if the type of a property is set according to the node type as well
+ * as no property is of type UNDEFINED. This test runs recursively through
+ * the entire repository.
+ */
+ public void testType() throws RepositoryException {
+ Session session = helper.getReadOnlySession();
+ Node root = session.getRootNode();
+ typeCheckChildren(root);
+ }
+
+ private void typeCheckChildren(Node parentNode)
+ throws RepositoryException {
+
+ NodeIterator nodes = parentNode.getNodes();
+ while (nodes.hasNext()) {
+ Node node = nodes.nextNode();
+
+ PropertyIterator props = node.getProperties();
+ while (props.hasNext()) {
+ Property prop = props.nextProperty();
+ int reqType = prop.getDefinition().getRequiredType();
+ int type = PropertyType.UNDEFINED;
+ boolean isEmptyMultipleArray = false;
+
+ if (prop.getDefinition().isMultiple()) {
+ if (prop.getValues().length > 0) {
+ type = prop.getValues()[0].getType();
+ } else {
+ isEmptyMultipleArray = true;
+ }
+ } else {
+ type = prop.getValue().getType();
+ }
+
+ if (!isEmptyMultipleArray &&
+ reqType != PropertyType.UNDEFINED) {
+
+ assertFalse("The type of a property must not " +
+ "be UNDEFINED",
+ type == PropertyType.UNDEFINED);
+
+ assertEquals("The type of a property has to match " +
+ "the type of the property definition.",
+ type,
+ reqType);
+ }
+ }
+ typeCheckChildren(node);
+ }
+ }
+
+
+}
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/PropertyTypeTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/TestAll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/TestAll.java?view=diff&r1=153935&r2=153936
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/TestAll.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/api/TestAll.java Tue Feb 15 05:56:44 2005
@@ -42,6 +42,10 @@
suite.addTestSuite(RootNodeTest.class);
suite.addTestSuite(NamespaceRegistryTest.class);
suite.addTestSuite(ReferencesTest.class);
+ suite.addTestSuite(ItemDefTest.class);
+ suite.addTestSuite(ItemReadMethodsTest.class);
+ suite.addTestSuite(NodeReadMethodsTest.class);
+ suite.addTestSuite(PropertyTypeTest.class);
return suite;
}