Author: mreutegg Date: Wed Oct 31 08:49:04 2012 New Revision: 1404038 URL: http://svn.apache.org/viewvc?rev=1404038&view=rev Log: OAK-66: JCR Node Type Management - use correct node type for child node based on child node definitions when no type is given on addNode()
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java?rev=1404038&r1=1404037&r2=1404038&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java Wed Oct 31 08:49:04 2012 @@ -32,6 +32,22 @@ public interface DefinitionProvider { @Nonnull NodeDefinition getRootDefinition() throws RepositoryException; + /** + * Returns the node definition for a child node of <code>parent</code> named + * <code>nodeName</code> with a default primary type. First the non-residual + * child node definitions of <code>parent</code> are checked matching the + * given node name. Then the residual definitions are checked. + * + * @param parent the parent node. + * @param nodeName the name of the child node. + * @return the applicable node definition. + * @throws RepositoryException if there is no applicable node definition + * with a default primary type. + */ + @Nonnull + NodeDefinition getDefinition(@Nonnull Node parent, @Nonnull String nodeName) + throws RepositoryException; + @Nonnull NodeDefinition getDefinition(Node parent, Node targetNode) throws RepositoryException; Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java?rev=1404038&r1=1404037&r2=1404038&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java Wed Oct 31 08:49:04 2012 @@ -54,6 +54,8 @@ import org.apache.jackrabbit.oak.util.No import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; import static javax.jcr.PropertyType.UNDEFINED; import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES; import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE; @@ -287,6 +289,36 @@ public abstract class ReadOnlyNodeTypeMa return new RootNodeDefinition(this); } + @Nonnull + @Override + public NodeDefinition getDefinition(@Nonnull Node parent, + @Nonnull String nodeName) + throws RepositoryException { + checkNotNull(parent); + checkNotNull(nodeName); + List<NodeDefinition> residualDefs = new ArrayList<NodeDefinition>(); + for (NodeType nt : getEffectiveNodeTypes(parent)) { + for (NodeDefinition def : nt.getDeclaredChildNodeDefinitions()) { + String defName = def.getName(); + if (nodeName.equals(defName) + && def.getDefaultPrimaryTypeName() != null) { + return def; + } else if ("*".equals(defName)) { + residualDefs.add(def); + } + } + } + + for (NodeDefinition def : residualDefs) { + if (def.getDefaultPrimaryTypeName() != null) { + // return the first definition with a default primary type + return def; + } + } + + throw new RepositoryException("No matching node definition found for " + this); + } + @Override public NodeDefinition getDefinition(@Nonnull Node parent, @Nonnull Node targetNode) throws RepositoryException { String name = targetNode.getName(); Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1404038&r1=1404037&r2=1404038&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (original) +++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Wed Oct 31 08:49:04 2012 @@ -73,6 +73,7 @@ import org.apache.jackrabbit.oak.api.Tre import org.apache.jackrabbit.oak.api.Tree.Status; import org.apache.jackrabbit.oak.commons.PathUtils; import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager; +import org.apache.jackrabbit.oak.plugins.nodetype.DefinitionProvider; import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants; import org.apache.jackrabbit.oak.util.TODO; import org.apache.jackrabbit.value.ValueHelper; @@ -244,8 +245,17 @@ public class NodeImpl extends ItemImpl<N throw new ItemExistsException(relPath); } - // TODO retrieve matching nt from effective definition based on name-matching. - String ntName = primaryNodeTypeName == null ? NodeType.NT_UNSTRUCTURED : primaryNodeTypeName; + String ntName = primaryNodeTypeName; + if (ntName == null) { + DefinitionProvider dp = sessionDelegate.getDefinitionProvider(); + try { + ntName = dp.getDefinition(new NodeImpl(parent), + PathUtils.getName(relPath)).getDefaultPrimaryTypeName(); + } catch (RepositoryException e) { + throw new ConstraintViolationException( + "no matching child node definition found for " + relPath); + } + } // TODO: figure out the right place for this check NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();