Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java (revision 841) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java (working copy) @@ -128,6 +128,10 @@ public static I18n autocreatedPropertyNeedsDefault; public static I18n singleValuedPropertyNeedsSingleValuedDefault; + public static I18n noDefinition; + public static I18n noSnsDefinition; + public static I18n missingMandatoryItem; + static { try { I18n.initialize(JcrI18n.class); Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeDefinition.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeDefinition.java (revision 841) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeDefinition.java (working copy) @@ -215,6 +215,25 @@ defaultPrimaryTypeName, required); } + + + @Override + public int hashCode() { + return getId().toString().hashCode(); + } + + @Override + public boolean equals( Object obj ) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + JcrNodeDefinition other = (JcrNodeDefinition)obj; + if (id == null) { + if (other.id != null) return false; + } else if (!id.equals(other.id)) return false; + return true; + } + /** * {@inheritDoc} * Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrPropertyDefinition.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrPropertyDefinition.java (revision 841) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrPropertyDefinition.java (working copy) @@ -310,7 +310,25 @@ throw new IllegalStateException("Invalid property type: " + type); } } + + @Override + public int hashCode() { + return getId().toString().hashCode(); + } + @Override + public boolean equals( Object obj ) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + JcrPropertyDefinition other = (JcrPropertyDefinition)obj; + if (id == null) { + if (other.id != null) return false; + } else if (!id.equals(other.id)) return false; + return true; + } + + /** * Interface that encapsulates a reusable method that can test values to determine if they match a specific list of * constraints for the semantics associated with a single {@link PropertyType}. Index: dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java (revision 841) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java (working copy) @@ -74,7 +74,7 @@ private final String stringRepresentation; /** - * Create a new identifier for a propety definition. + * Create a new identifier for a property definition. * * @param nodeTypeName the name of the node type; may not be null * @param propertyDefinitionName the name of the property definition, which may be a {@link #ANY_NAME residual property}; may Index: dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java (revision 841) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java (working copy) @@ -355,12 +356,205 @@ } /** + * Checks that the child items of the node are consistent with the definitions required by the node's primary type and mixin + * types (if any). + *

+ * This method first checks that all of the child nodes and properties for the node have definitions based on the current + * primary and mixin node types for the node as held in the node type registry. The method then checks that all mandatory (and + * non-protected) items are populated. + *

+ * + * @param nodeUuid the UUID of the node to check + * @param checkSns if true indicates that this method should distinguish between child nodes that have no matching definition + * and child nodes that would have a definition that would match if it allowed same-name siblings. This flag determines + * which exception type should be thrown in that case. + * @throws ItemExistsException if checkSns is true and there is no definition that allows same-name siblings for one of the + * node's child nodes and the node already has a child node with the given name + * @throws ConstraintViolationException if one of the node's properties or child nodes does not have a matching definition for + * the name and type among the node's primary and mixin types; this should only occur if type definitions have been + * modified since the node was loaded or modified. + * @throws RepositoryException if any other error occurs + */ + private void checkAgainstTypeDefinitions( UUID nodeUuid, + boolean checkSns ) + throws ConstraintViolationException, ItemExistsException, RepositoryException { + + NodeInfo nodeInfo = findNodeInfo(nodeUuid); + AbstractJcrNode node = findJcrNode(nodeUuid); + + Name primaryTypeName = node.getPrimaryTypeName(); + List mixinTypeNames = node.getMixinTypeNames(); + Set satisfiedChildNodes = new HashSet(); + Set satisfiedProperties = new HashSet(); + + for (AbstractJcrProperty property : findJcrPropertiesFor(nodeUuid)) { + JcrPropertyDefinition definition = findBestPropertyDefintion(primaryTypeName, + mixinTypeNames, + property.property(), + property.getType(), + false); + if (definition == null) { + throw new ConstraintViolationException(JcrI18n.noDefinition.text("property", + property.getName(), + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + + satisfiedProperties.add(definition); + } + + Children children = nodeInfo.getChildren(); + for (ChildNode child : children) { + int snsCount = children.getCountOfSameNameSiblingsWithName(child.getName()); + NodeInfo childInfo = findNodeInfo(child.getUuid()); + JcrNodeDefinition definition = nodeTypes().findChildNodeDefinition(primaryTypeName, + mixinTypeNames, + child.getName(), + childInfo.getPrimaryTypeName(), + snsCount, + false); + if (definition == null) { + if (checkSns && snsCount > 1) { + definition = nodeTypes().findChildNodeDefinition(primaryTypeName, + mixinTypeNames, + child.getName(), + childInfo.getPrimaryTypeName(), + 1, + false); + + if (definition != null) { + throw new ItemExistsException(JcrI18n.noSnsDefinition.text(child.getName(), + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + } + throw new ConstraintViolationException(JcrI18n.noDefinition.text("child node", + child.getName(), + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + satisfiedChildNodes.add(definition); + } + + JcrNodeType primaryType = nodeTypes().getNodeType(primaryTypeName); + for (JcrPropertyDefinition definition : primaryType.getPropertyDefinitions()) { + if (definition.isMandatory() && !definition.isProtected() && !satisfiedProperties.contains(definition)) { + throw new ConstraintViolationException(JcrI18n.noDefinition.text("property", + definition.getName(), + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + } + for (JcrNodeDefinition definition : primaryType.getChildNodeDefinitions()) { + if (definition.isMandatory() && !definition.isProtected() && !satisfiedChildNodes.contains(definition)) { + throw new ConstraintViolationException(JcrI18n.noDefinition.text("child node", + definition.getName(), + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + } + + for (Name mixinTypeName : mixinTypeNames) { + JcrNodeType mixinType = nodeTypes().getNodeType(mixinTypeName); + for (JcrPropertyDefinition definition : mixinType.getPropertyDefinitions()) { + if (definition.isMandatory() && !definition.isProtected() && !satisfiedProperties.contains(definition)) { + throw new ConstraintViolationException(JcrI18n.noDefinition.text("child node", + definition.getName(), + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + } + for (JcrNodeDefinition definition : mixinType.getChildNodeDefinitions()) { + if (definition.isMandatory() && !definition.isProtected() && !satisfiedChildNodes.contains(definition)) { + throw new ConstraintViolationException(JcrI18n.noDefinition.text("child node", + definition.getName(), + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + } + + } + } + + /** + * Find the best definition for the child node with the given name on the node with the given UUID. + * + * @param nodeUuid the parent node; may not be null + * @param newNodeName the name of the potential new child node; may not be null + * @param newNodePrimaryTypeName the primary type of the potential new child node; may not be null + * @return the definition that best fits the new node name and type + * @throws ItemExistsException if there is no definition that allows same-name siblings for the name and type and the parent + * node already has a child node with the given name + * @throws ConstraintViolationException if there is no definition for the name and type among the parent node's primary and + * mixin types + * @throws RepositoryException if any other error occurs + */ + private JcrNodeDefinition findBestNodeDefinition( UUID nodeUuid, + Name newNodeName, + Name newNodePrimaryTypeName ) + throws ItemExistsException, ConstraintViolationException, RepositoryException { + assert (nodeUuid != null); + assert (newNodeName != null); + + NodeInfo nodeInfo = findNodeInfo(nodeUuid); + AbstractJcrNode node = findJcrNode(nodeUuid); + + Name primaryTypeName = node.getPrimaryTypeName(); + List mixinTypeNames = node.getMixinTypeNames(); + + Children children = nodeInfo.getChildren(); + int snsCount = children.getCountOfSameNameSiblingsWithName(newNodeName); + JcrNodeDefinition definition = nodeTypes().findChildNodeDefinition(primaryTypeName, + mixinTypeNames, + newNodeName, + newNodePrimaryTypeName, + snsCount, + true); + if (definition == null) { + if (snsCount > 1) { + definition = nodeTypes().findChildNodeDefinition(primaryTypeName, + mixinTypeNames, + newNodeName, + newNodePrimaryTypeName, + 1, + true); + + if (definition != null) { + throw new ItemExistsException(JcrI18n.noSnsDefinition.text(newNodeName, + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + } + + throw new ConstraintViolationException(JcrI18n.noDefinition.text("child node", + newNodeName, + node.getPath(), + primaryTypeName, + mixinTypeNames)); + } + + return definition; + } + + /** * Save any changes that have been accumulated by this session. * * @throws RepositoryException if any error resulting while saving the changes to the repository */ public void save() throws RepositoryException { if (operations.isExecuteRequired()) { + for (UUID changedUuid : changedNodes.keySet()) { + checkAgainstTypeDefinitions(changedUuid, false); + } + // Execute the batched operations ... try { operations.execute(); @@ -452,10 +647,33 @@ for (ChildNode childNode : changedNode.getChildren()) { uuidsUnderBranch.add(childNode.getUuid()); } + + Collection peers = changedNode.getPeers(); + if (peers != null) peersToCheck.addAll(peers); } } + /* + * Need to check that any peers in a Session.move operation are both in the save + */ + for (UUID peerUuid : peersToCheck) { + if (!uuidsUnderBranch.contains(peerUuid)) { + throw new ConstraintViolationException(); + } + } + + /* + * Also need to check that constraints are met + */ + for (UUID changedUuid : uuidsUnderBranch) { + NodeInfo deletedNodeInfo = deletedNodes.get(changedUuid); + if (deletedNodeInfo != null) { + // Need to check that the parent still matches + checkAgainstTypeDefinitions(deletedNodeInfo.getParent(), false); + } else checkAgainstTypeDefinitions(changedUuid, false); + } + // Now execute the branch ... Graph.Batch branchBatch = store.batch(new BatchRequestBuilder(branchRequests)); try { @@ -1154,7 +1531,7 @@ } /** - * Find the best property definition in this node's + * Find the best property definition in this node's primary type and mixin types. * * @param primaryTypeNameOfParent the name of the primary type for the parent node; may not be null * @param mixinTypeNamesOfParent the names of the mixin types for the parent node; may be null or empty if there are no mixins Index: dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties =================================================================== --- dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties (revision 841) +++ dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties (working copy) @@ -112,3 +112,7 @@ cannotRedefineProperty=Cannot redefine property '{0}' with new type '{1}' when existing property with same name in type '{2}' has incompatible type '{3}' autocreatedPropertyNeedsDefault=Auto-created property '{0}' in type '{1}' must specify a default value singleValuedPropertyNeedsSingleValuedDefault=Single-valued property '{0}' in type '{1}' cannot have multiple default values + +noDefinition=Cannot find a definition for the {0} named '{1}' on the node at '{2}' with primary type '{3}' and mixin types: {4} +noSnsDefinition=Cannot find a definition that allows same-name siblings for the child node named '{0}' on the node at '{1}' with primary type '{2}' and mixin types: {3} and a child node already exists with this name +missingMandatoryItem=The mandatory {0} named '{1}' defined in type '{2}' is missing from the node at '{3}' Index: dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java (revision 841) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java (working copy) @@ -35,21 +35,28 @@ import java.util.Map; import java.util.Properties; import javax.jcr.Credentials; +import javax.jcr.PropertyType; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.jackrabbit.test.JCRTestSuite; import org.apache.jackrabbit.test.RepositoryStub; import org.apache.jackrabbit.test.api.AddNodeTest; +import org.apache.jackrabbit.test.api.DocumentViewImportTest; import org.apache.jackrabbit.test.api.NamespaceRegistryTest; import org.apache.jackrabbit.test.api.NodeAddMixinTest; import org.apache.jackrabbit.test.api.NodeCanAddMixinTest; import org.apache.jackrabbit.test.api.NodeItemIsModifiedTest; import org.apache.jackrabbit.test.api.NodeItemIsNewTest; import org.apache.jackrabbit.test.api.NodeRemoveMixinTest; +import org.apache.jackrabbit.test.api.NodeTest; +import org.apache.jackrabbit.test.api.NodeUUIDTest; import org.apache.jackrabbit.test.api.PropertyItemIsModifiedTest; import org.apache.jackrabbit.test.api.PropertyItemIsNewTest; import org.apache.jackrabbit.test.api.PropertyTest; +import org.apache.jackrabbit.test.api.ReferencesTest; import org.apache.jackrabbit.test.api.RepositoryLoginTest; +import org.apache.jackrabbit.test.api.SerializationTest; +import org.apache.jackrabbit.test.api.SessionTest; import org.apache.jackrabbit.test.api.SessionUUIDTest; import org.apache.jackrabbit.test.api.SetPropertyBooleanTest; import org.apache.jackrabbit.test.api.SetPropertyCalendarTest; @@ -77,7 +84,14 @@ import org.apache.jackrabbit.test.api.WorkspaceCopyBetweenWorkspacesReferenceableTest; import org.apache.jackrabbit.test.api.WorkspaceCopyBetweenWorkspacesSameNameSibsTest; import org.apache.jackrabbit.test.api.WorkspaceCopyBetweenWorkspacesTest; +import org.apache.jackrabbit.test.api.WorkspaceCopyBetweenWorkspacesVersionableTest; +import org.apache.jackrabbit.test.api.WorkspaceCopyReferenceableTest; +import org.apache.jackrabbit.test.api.WorkspaceCopySameNameSibsTest; +import org.apache.jackrabbit.test.api.WorkspaceCopyTest; import org.apache.jackrabbit.test.api.WorkspaceCopyVersionableTest; +import org.apache.jackrabbit.test.api.WorkspaceMoveReferenceableTest; +import org.apache.jackrabbit.test.api.WorkspaceMoveSameNameSibsTest; +import org.apache.jackrabbit.test.api.WorkspaceMoveTest; import org.apache.jackrabbit.test.api.WorkspaceMoveVersionableTest; import org.jboss.dna.graph.ExecutionContext; import org.jboss.dna.graph.Graph; @@ -188,11 +202,11 @@ // level 2 tests addTestSuite(AddNodeTest.class); addTestSuite(NamespaceRegistryTest.class); - // addTestSuite(ReferencesTest.class); - // addTestSuite(SessionTest.class); + addTestSuite(ReferencesTest.class); + addTestSuite(SessionTest.class); addTestSuite(SessionUUIDTest.class); - // addTestSuite(NodeTest.class); - // addTestSuite(NodeUUIDTest.class); + addTestSuite(NodeTest.class); + addTestSuite(NodeUUIDTest.class); // addTestSuite(NodeOrderableChildNodesTest.class); addTestSuite(PropertyTest.class); @@ -234,22 +248,22 @@ addTestSuite(WorkspaceCopyBetweenWorkspacesReferenceableTest.class); addTestSuite(WorkspaceCopyBetweenWorkspacesSameNameSibsTest.class); addTestSuite(WorkspaceCopyBetweenWorkspacesTest.class); - // addTestSuite(WorkspaceCopyBetweenWorkspacesVersionableTest.class); - // addTestSuite(WorkspaceCopyReferenceableTest.class); - // addTestSuite(WorkspaceCopySameNameSibsTest.class); - // addTestSuite(WorkspaceCopyTest.class); + addTestSuite(WorkspaceCopyBetweenWorkspacesVersionableTest.class); + addTestSuite(WorkspaceCopyReferenceableTest.class); + addTestSuite(WorkspaceCopySameNameSibsTest.class); + addTestSuite(WorkspaceCopyTest.class); addTestSuite(WorkspaceCopyVersionableTest.class); - // addTestSuite(WorkspaceMoveReferenceableTest.class); - // addTestSuite(WorkspaceMoveSameNameSibsTest.class); - // addTestSuite(WorkspaceMoveTest.class); + addTestSuite(WorkspaceMoveReferenceableTest.class); + addTestSuite(WorkspaceMoveSameNameSibsTest.class); + addTestSuite(WorkspaceMoveTest.class); addTestSuite(WorkspaceMoveVersionableTest.class); addTestSuite(RepositoryLoginTest.class); // addTestSuite(ImpersonateTest.class); // addTestSuite(CheckPermissionTest.class); - // addTestSuite(DocumentViewImportTest.class); - // addTestSuite(SerializationTest.class); + addTestSuite(DocumentViewImportTest.class); + addTestSuite(SerializationTest.class); addTestSuite(ValueFactoryTest.class); } @@ -264,7 +278,7 @@ // We currently don't pass the tests in those suites that are commented out // See https://jira.jboss.org/jira/browse/DNA-285 - // addTest(org.apache.jackrabbit.test.api.observation.TestAll.suite()); + addTest(org.apache.jackrabbit.test.api.observation.TestAll.suite()); // addTest(org.apache.jackrabbit.test.api.version.TestAll.suite()); // addTest(org.apache.jackrabbit.test.api.lock.TestAll.suite()); addTest(org.apache.jackrabbit.test.api.util.TestAll.suite()); @@ -456,10 +470,52 @@ TestLexicon.REFERENCEABLE_UNSTRUCTURED, Arrays.asList(new JcrNodeType[] {unstructured, referenceable}), NO_PRIMARY_ITEM_NAME, NO_CHILD_NODES, NO_PROPERTIES, - NOT_MIXIN, UNORDERABLE_CHILD_NODES); + NOT_MIXIN, ORDERABLE_CHILD_NODES); - nodeTypes.addAll(Arrays.asList(new JcrNodeType[] {referenceableUnstructured, noSameNameSibs})); + JcrNodeType nodeWithMandatoryProperty = new JcrNodeType( + context, + NO_NODE_TYPE_MANAGER, + TestLexicon.NODE_WITH_MANDATORY_PROPERTY, + Arrays.asList(new JcrNodeType[] {unstructured, referenceable}), + NO_PRIMARY_ITEM_NAME, + NO_CHILD_NODES, + Arrays.asList(new JcrPropertyDefinition[] {new JcrPropertyDefinition( + context, + null, + TestLexicon.MANDATORY_STRING, + OnParentVersionBehavior.COPY.getJcrValue(), + false, + true, + false, + NO_DEFAULT_VALUES, + PropertyType.UNDEFINED, + NO_CONSTRAINTS, + false)}), + NOT_MIXIN, ORDERABLE_CHILD_NODES); + JcrNodeType nodeWithMandatoryChild = new JcrNodeType( + context, + NO_NODE_TYPE_MANAGER, + TestLexicon.NODE_WITH_MANDATORY_CHILD, + Arrays.asList(new JcrNodeType[] {unstructured, referenceable}), + NO_PRIMARY_ITEM_NAME, + Arrays.asList(new JcrNodeDefinition[] {new JcrNodeDefinition( + context, + null, + TestLexicon.MANDATORY_CHILD, + OnParentVersionBehavior.VERSION.getJcrValue(), + false, + true, + false, + false, + JcrNtLexicon.UNSTRUCTURED, + new JcrNodeType[] {base}),}), + NO_PROPERTIES, + NOT_MIXIN, ORDERABLE_CHILD_NODES); + + nodeTypes.addAll(Arrays.asList(new JcrNodeType[] {referenceableUnstructured, noSameNameSibs, + nodeWithMandatoryProperty, nodeWithMandatoryChild, })); + } /** Index: dna-jcr/src/test/java/org/jboss/dna/jcr/TestLexicon.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/TestLexicon.java (revision 841) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/TestLexicon.java (working copy) @@ -47,7 +47,12 @@ public static final Name CONSTRAINED_REFERENCE = new BasicName(Namespace.URI, "constrainedReference"); public static final Name CONSTRAINED_STRING = new BasicName(Namespace.URI, "constrainedString"); + public static final Name MANDATORY_STRING = new BasicName(Namespace.URI, "mandatoryString"); + public static final Name MANDATORY_CHILD = new BasicName(Namespace.URI, "mandatoryChild"); + public static final Name REFERENCEABLE_UNSTRUCTURED = new BasicName(Namespace.URI, "referenceableUnstructured"); public static final Name NO_SAME_NAME_SIBS = new BasicName(Namespace.URI, "noSameNameSibs"); + public static final Name NODE_WITH_MANDATORY_PROPERTY = new BasicName(Namespace.URI, "nodeWithMandatoryProperty"); + public static final Name NODE_WITH_MANDATORY_CHILD = new BasicName(Namespace.URI, "nodeWithMandatoryChild"); } Index: dna-jcr/src/test/resources/repositoryStubImpl.properties =================================================================== --- dna-jcr/src/test/resources/repositoryStubImpl.properties (revision 841) +++ dna-jcr/src/test/resources/repositoryStubImpl.properties (working copy) @@ -9,11 +9,11 @@ javax.jcr.tck.workspacename= javax.jcr.tck.nodetype=dnatest\:referenceableUnstructured javax.jcr.tck.nodetypenochildren=dna:namespace -javax.jcr.tck.sourceFolderName=source -javax.jcr.tck.targetFolderName=target +javax.jcr.tck.sourceFolderName=source +javax.jcr.tck.targetFolderName=target javax.jcr.tck.rootNodeName=rootNode javax.jcr.tck.propertySkipped=propertySkipped -javax.jcr.tck.propertyValueMayChange=propertyValueMayChange +javax.jcr.tck.propertyValueMayChange=propertyValueMayChange javax.jcr.tck.nodeTypesTestNode=nodeTypesTestNode javax.jcr.tck.mixinTypeTestNode=mixinTypeTestNode javax.jcr.tck.propertyTypesTestNode=propertyTypesTestNode @@ -22,6 +22,8 @@ javax.jcr.tck.referenceableNodeTestNode=referenceableNodeTestNode javax.jcr.tck.orderChildrenTestNode=orderChildrenTestNode javax.jcr.tck.namespaceTestNode=namespaceTestNode +javax.jcr.tck.sameNameSibsTrueNodeType=nt\:unstructured +javax.jcr.tck.sameNameSibsFalseNodeType=dnatest\:noSameNameSibs javax.jcr.tck.sameNameSibsFalseChildNodeDefinition=dnatest\:noSameNameSibs javax.jcr.tck.stringTestProperty=stringTestProperty javax.jcr.tck.binaryTestProperty=binaryTestProperty @@ -33,4 +35,10 @@ javax.jcr.tck.pathTestProperty=pathTestProperty javax.jcr.tck.referenceTestProperty=referenceTestProperty javax.jcr.tck.multiValueTestProperty=multiValueTestProperty -javax.jcr.tck.NodeTest.testAddNodeItemExistsException.nodetype=dnatest\:noSameNameSibs \ No newline at end of file +javax.jcr.tck.NodeTest.testAddNodeItemExistsException.nodetype=dnatest\:noSameNameSibs +javax.jcr.tck.NodeOrderableChildNodesTest.nodetype2=dnatest\:referenceableUnstructured +javax.jcr.tck.SessionTest.testSaveContstraintViolationException.nodetype2=dnatest\:nodeWithMandatoryProperty +javax.jcr.tck.NodeTest.testRemoveMandatoryNode.nodetype2=dnatest\:nodeWithMandatoryChild +javax.jcr.tck.NodeTest.testRemoveMandatoryNode.nodename3=dnatest\:mandatoryChild +javax.jcr.tck.NodeTest.testSaveContstraintViolationException.nodetype2=dnatest\:nodeWithMandatoryProperty +