You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2016/05/19 07:59:54 UTC
svn commit: r1744526 - in /jackrabbit/oak/branches/1.2:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/
oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/node...
Author: tomekr
Date: Thu May 19 07:59:54 2016
New Revision: 1744526
URL: http://svn.apache.org/viewvc?rev=1744526&view=rev
Log:
OAK-3584 : PathNotFoundException when reading child node and property definitions below nt root
Added:
jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeDefinitionTest.java
Modified:
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeTemplateImpl.java
Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java?rev=1744526&r1=1744525&r2=1744526&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java Thu May 19 07:59:54 2016
@@ -20,16 +20,16 @@ import static com.google.common.base.Pre
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newTreeMap;
import static java.util.Collections.emptyList;
-import static org.apache.jackrabbit.JcrConstants.JCR_CHILDNODEDEFINITION;
import static org.apache.jackrabbit.JcrConstants.JCR_HASORDERABLECHILDNODES;
import static org.apache.jackrabbit.JcrConstants.JCR_ISMIXIN;
import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
import static org.apache.jackrabbit.JcrConstants.JCR_NODETYPENAME;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYITEMNAME;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
-import static org.apache.jackrabbit.JcrConstants.JCR_PROPERTYDEFINITION;
import static org.apache.jackrabbit.JcrConstants.JCR_SUPERTYPES;
import static org.apache.jackrabbit.JcrConstants.JCR_UUID;
+import static org.apache.jackrabbit.JcrConstants.NT_CHILDNODEDEFINITION;
+import static org.apache.jackrabbit.JcrConstants.NT_PROPERTYDEFINITION;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_IS_ABSTRACT;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_IS_QUERYABLE;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.REP_DECLARING_NODE_TYPE;
@@ -52,8 +52,6 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -68,6 +66,9 @@ import javax.jcr.nodetype.NodeTypeDefini
import javax.jcr.nodetype.NodeTypeIterator;
import javax.jcr.nodetype.PropertyDefinition;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -103,16 +104,6 @@ class NodeTypeImpl extends AbstractTypeD
private static final Logger log = LoggerFactory.getLogger(NodeTypeImpl.class);
- /**
- * Name pattern for the property and child node definition nodes.
- * Used to pick out the SNS indices from the names so the definitions
- * can be sorted in the same order they were created. This in turn
- * makes accessing node type information more deterministic.
- */
- private static final Pattern DEFINITION_PATTERN = Pattern.compile(
- "(" + JCR_PROPERTYDEFINITION + "|" + JCR_CHILDNODEDEFINITION
- + ")\\[([1-9][0-9]*)\\]");
-
private static final PropertyDefinition[] NO_PROPERTY_DEFINITIONS =
new PropertyDefinition[0];
@@ -198,14 +189,8 @@ class NodeTypeImpl extends AbstractTypeD
@Override @Nonnull
public PropertyDefinition[] getDeclaredPropertyDefinitions() {
Map<Integer, PropertyDefinition> definitions = newTreeMap();
- for (Tree child : definition.getChildren()) {
- Matcher matcher = DEFINITION_PATTERN.matcher(child.getName());
- if (matcher.matches()
- && JCR_PROPERTYDEFINITION.equals(matcher.group(1))) {
- definitions.put(
- Integer.valueOf(matcher.group(2)),
- new PropertyDefinitionImpl(child, this, mapper));
- }
+ for (Tree child : Iterables.filter(definition.getChildren(), PrimaryTypePredicate.PROPERTY_DEF_PREDICATE)) {
+ definitions.put(getIndex(child), new PropertyDefinitionImpl(child, this, mapper));
}
return definitions.values().toArray(NO_PROPERTY_DEFINITIONS);
}
@@ -218,14 +203,8 @@ class NodeTypeImpl extends AbstractTypeD
@Override @Nonnull
public NodeDefinition[] getDeclaredChildNodeDefinitions() {
Map<Integer, NodeDefinition> definitions = newTreeMap();
- for (Tree child : definition.getChildren()) {
- Matcher matcher = DEFINITION_PATTERN.matcher(child.getName());
- if (matcher.matches()
- && JCR_CHILDNODEDEFINITION.equals(matcher.group(1))) {
- definitions.put(
- Integer.valueOf(matcher.group(2)),
- new NodeDefinitionImpl(child, this, mapper));
- }
+ for (Tree child : Iterables.filter(definition.getChildren(), PrimaryTypePredicate.CHILDNODE_DEF_PREDICATE)) {
+ definitions.put(getIndex(child), new NodeDefinitionImpl(child, this, mapper));
}
return definitions.values().toArray(NO_NODE_DEFINITIONS);
}
@@ -709,6 +688,12 @@ class NodeTypeImpl extends AbstractTypeD
return true;
}
+ private static int getIndex(@Nonnull Tree tree) {
+ String name = tree.getName();
+ int i = name.lastIndexOf('[');
+ return (i == -1) ? 1 : Integer.valueOf(name.substring(i+1, name.lastIndexOf(']')));
+ }
+
private boolean matches(String childNodeName, String name) {
String oakChildName = mapper.getOakNameOrNull(childNodeName);
String oakName = mapper.getOakNameOrNull(name);
@@ -716,4 +701,20 @@ class NodeTypeImpl extends AbstractTypeD
return oakChildName != null && oakChildName.startsWith(oakName);
}
+ private static final class PrimaryTypePredicate implements Predicate<Tree> {
+
+ private static final PrimaryTypePredicate PROPERTY_DEF_PREDICATE = new PrimaryTypePredicate(NT_PROPERTYDEFINITION);
+ private static final PrimaryTypePredicate CHILDNODE_DEF_PREDICATE = new PrimaryTypePredicate(NT_CHILDNODEDEFINITION);
+
+ private final String primaryTypeName;
+
+ private PrimaryTypePredicate(@Nonnull String primaryTypeName) {
+ this.primaryTypeName = primaryTypeName;
+ }
+
+ @Override
+ public boolean apply(Tree tree) {
+ return primaryTypeName.equals(TreeUtil.getPrimaryTypeName(tree));
+ }
+ }
}
Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeTemplateImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeTemplateImpl.java?rev=1744526&r1=1744525&r2=1744526&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeTemplateImpl.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeTemplateImpl.java Thu May 19 07:59:54 2016
@@ -34,6 +34,7 @@ import static org.apache.jackrabbit.oak.
import java.util.Arrays;
import java.util.List;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.ConstraintViolationException;
@@ -165,48 +166,36 @@ class NodeTypeTemplateImpl extends Named
type.removeProperty(JCR_PRIMARYITEMNAME);
}
- Tree tree;
// TODO fail (in validator?) on invalid item definitions
// See 3.7.6.8 Item Definitions in Subtypes (OAK-411)
- int pdn = 1;
- if (propertyDefinitionTemplates != null) {
- for (PropertyDefinitionTemplateImpl pdt : propertyDefinitionTemplates) {
- String name = JCR_PROPERTYDEFINITION + "[" + pdn++ + "]";
- tree = type.getChild(name);
- if (!tree.exists()) {
- tree = type.addChild(name);
- tree.setProperty(
- JCR_PRIMARYTYPE, NT_PROPERTYDEFINITION, NAME);
- }
- pdt.writeTo(tree);
- }
- }
- tree = type.getChild(JCR_PROPERTYDEFINITION + "[" + pdn++ + "]");
- while (tree.exists()) {
- tree.remove();
- tree = type.getChild(JCR_PROPERTYDEFINITION + "[" + pdn++ + "]");
- }
+ writeItemDefinitions(type, propertyDefinitionTemplates, JCR_PROPERTYDEFINITION, NT_PROPERTYDEFINITION);
+ writeItemDefinitions(type, nodeDefinitionTemplates, JCR_CHILDNODEDEFINITION, NT_CHILDNODEDEFINITION);
+
+ return type;
+ }
- int ndn = 1;
- if (nodeDefinitionTemplates != null) {
- for (NodeDefinitionTemplateImpl ndt : nodeDefinitionTemplates) {
- String name = JCR_CHILDNODEDEFINITION + "[" + ndn++ + "]";
- tree = type.getChild(name);
+ private static void writeItemDefinitions(@Nonnull Tree nodeTypeTree, @CheckForNull List<? extends ItemDefinitionTemplate> itemDefTemplates,
+ @Nonnull String nodeName, @Nonnull String primaryTypeName) throws RepositoryException {
+ Tree tree;
+ int index = 1;
+ if (itemDefTemplates != null) {
+ for (ItemDefinitionTemplate template : itemDefTemplates) {
+ String name = (index == 1) ? nodeName : nodeName + '[' + index + ']';
+ tree = nodeTypeTree.getChild(name);
if (!tree.exists()) {
- tree = type.addChild(name);
+ tree = nodeTypeTree.addChild(name);
tree.setProperty(
- JCR_PRIMARYTYPE, NT_CHILDNODEDEFINITION, NAME);
+ JCR_PRIMARYTYPE, primaryTypeName, NAME);
}
- ndt.writeTo(tree);
+ template.writeTo(tree);
+ index++;
}
}
- tree = type.getChild(JCR_CHILDNODEDEFINITION + "[" + ndn++ + "]");
+ tree = nodeTypeTree.getChild(nodeName + '[' + index++ + ']');
while (tree.exists()) {
tree.remove();
- tree = type.getChild(JCR_CHILDNODEDEFINITION + "[" + ndn++ + "]");
+ tree = nodeTypeTree.getChild(nodeName + '[' + index++ + ']');
}
-
- return type;
}
//------------------------------------------------------------< public >--
Added: jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeDefinitionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeDefinitionTest.java?rev=1744526&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeDefinitionTest.java (added)
+++ jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeDefinitionTest.java Thu May 19 07:59:54 2016
@@ -0,0 +1,105 @@
+/*
+ * 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.oak.jcr.nodetype;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.jcr.ItemVisitor;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.util.TraversingItemVisitor;
+
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+public class NodeTypeDefinitionTest extends AbstractJCRTest {
+
+ public void testReadNodeTypeTree() throws Exception {
+ String ntPath = NodeTypeConstants.NODE_TYPES_PATH + '/' + NodeTypeConstants.NT_UNSTRUCTURED;
+
+ Node ntNode = superuser.getNode(ntPath);
+ ItemVisitor visitor = new TraversingItemVisitor.Default() {
+ @Override
+ protected void entering(Node node, int level) throws RepositoryException {
+ assertTrue(superuser.nodeExists(node.getPath()));
+ super.entering(node, level);
+ }
+ };
+ visitor.visit(ntNode);
+
+ }
+
+ public void testIndexedChildDefinition() throws Exception {
+ String ntPath = NodeTypeConstants.NODE_TYPES_PATH + '/' + NodeTypeConstants.NT_VERSIONHISTORY;
+ assertTrue(superuser.nodeExists(ntPath + "/jcr:childNodeDefinition"));
+ assertTrue(superuser.nodeExists(ntPath + "/jcr:childNodeDefinition[1]"));
+
+ Node cdNode = superuser.getNode(ntPath + "/jcr:childNodeDefinition[1]");
+ assertEquals(ntPath + "/jcr:childNodeDefinition", cdNode.getPath());
+
+ List<String> defNames = new ArrayList();
+ NodeType nt = superuser.getWorkspace().getNodeTypeManager().getNodeType(NodeTypeConstants.NT_VERSIONHISTORY);
+ for (NodeDefinition nd : nt.getDeclaredChildNodeDefinitions()) {
+ defNames.add(nd.getName());
+ }
+
+ Node ntNode = superuser.getNode(ntPath);
+ NodeIterator it = ntNode.getNodes("jcr:childNodeDefinition*");
+ while (it.hasNext()) {
+ Node def = it.nextNode();
+ int index = getIndex(def);
+ String name = (def.hasProperty(NodeTypeConstants.JCR_NAME)) ? def.getProperty(NodeTypeConstants.JCR_NAME).getString() : NodeTypeConstants.RESIDUAL_NAME;
+ assertEquals(name, defNames.get(index-1));
+ }
+ }
+
+ public void testIndexedPropertyDefinition() throws Exception {
+ String ntPath = NodeTypeConstants.NODE_TYPES_PATH + '/' + NodeTypeConstants.NT_VERSION;
+
+ assertTrue(superuser.nodeExists(ntPath + "/jcr:propertyDefinition"));
+ assertTrue(superuser.nodeExists(ntPath + "/jcr:propertyDefinition[1]"));
+
+ Node pdNode = superuser.getNode(ntPath + "/jcr:propertyDefinition[1]");
+ assertEquals(ntPath + "/jcr:propertyDefinition", pdNode.getPath());
+
+ List<String> defNames = new ArrayList();
+ NodeType nt = superuser.getWorkspace().getNodeTypeManager().getNodeType(NodeTypeConstants.NT_VERSION);
+ for (PropertyDefinition nd : nt.getDeclaredPropertyDefinitions()) {
+ defNames.add(nd.getName());
+ }
+
+ Node ntNode = superuser.getNode(ntPath);
+ NodeIterator it = ntNode.getNodes("jcr:propertyDefinition*");
+ while (it.hasNext()) {
+ Node def = it.nextNode();
+ int index = getIndex(def);
+ String name = (def.hasProperty(NodeTypeConstants.JCR_NAME)) ? def.getProperty(NodeTypeConstants.JCR_NAME).getString() : NodeTypeConstants.RESIDUAL_NAME;
+ assertEquals(name, defNames.get(index-1));
+ }
+ }
+
+ private static int getIndex(@Nonnull Node node) throws RepositoryException {
+ String name = node.getName();
+ int i = name.lastIndexOf('[');
+ return (i == -1) ? 1 : Integer.valueOf(name.substring(i+1, name.lastIndexOf(']')));
+ }
+}
\ No newline at end of file