Return-Path: X-Original-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A2DAB108BA for ; Fri, 26 Apr 2013 08:24:35 +0000 (UTC) Received: (qmail 25780 invoked by uid 500); 26 Apr 2013 08:24:35 -0000 Delivered-To: apmail-jackrabbit-oak-commits-archive@jackrabbit.apache.org Received: (qmail 25722 invoked by uid 500); 26 Apr 2013 08:24:34 -0000 Mailing-List: contact oak-commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: oak-dev@jackrabbit.apache.org Delivered-To: mailing list oak-commits@jackrabbit.apache.org Received: (qmail 25705 invoked by uid 99); 26 Apr 2013 08:24:34 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 26 Apr 2013 08:24:34 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 26 Apr 2013 08:24:32 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 9390223888E3; Fri, 26 Apr 2013 08:24:12 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1476096 - in /jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr: NodeImpl.java delegate/NodeDelegate.java Date: Fri, 26 Apr 2013 08:24:12 -0000 To: oak-commits@jackrabbit.apache.org From: jukka@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130426082412.9390223888E3@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jukka Date: Fri Apr 26 08:24:12 2013 New Revision: 1476096 URL: http://svn.apache.org/r1476096 Log: OAK-702: Optimize access to node type information Optimize generation of auto-created content Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java 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=1476096&r1=1476095&r2=1476096&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 Fri Apr 26 08:24:12 2013 @@ -258,9 +258,7 @@ public class NodeImpl childNode = new NodeImpl(added, sessionContext); - childNode.autoCreateItems(); - return childNode; + return new NodeImpl(added, sessionContext); } }); } Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java?rev=1476096&r1=1476095&r2=1476096&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java (original) +++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java Fri Apr 26 08:24:12 2013 @@ -18,19 +18,31 @@ package org.apache.jackrabbit.oak.jcr.de import static com.google.common.collect.Lists.newArrayList; import static java.util.Collections.emptyList; +import static org.apache.jackrabbit.JcrConstants.JCR_AUTOCREATED; +import static org.apache.jackrabbit.JcrConstants.JCR_CREATED; import static org.apache.jackrabbit.JcrConstants.JCR_DEFAULTPRIMARYTYPE; +import static org.apache.jackrabbit.JcrConstants.JCR_DEFAULTVALUES; import static org.apache.jackrabbit.JcrConstants.JCR_HASORDERABLECHILDNODES; import static org.apache.jackrabbit.JcrConstants.JCR_ISMIXIN; +import static org.apache.jackrabbit.JcrConstants.JCR_LASTMODIFIED; import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES; +import static org.apache.jackrabbit.JcrConstants.JCR_MULTIPLE; import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE; +import static org.apache.jackrabbit.JcrConstants.JCR_UUID; import static org.apache.jackrabbit.oak.api.Type.BOOLEAN; +import static org.apache.jackrabbit.oak.api.Type.DATE; import static org.apache.jackrabbit.oak.api.Type.NAME; import static org.apache.jackrabbit.oak.api.Type.NAMES; +import static org.apache.jackrabbit.oak.api.Type.STRING; +import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_CREATEDBY; import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_IS_ABSTRACT; +import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_LASTMODIFIEDBY; import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.NODE_TYPES_PATH; import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_NAMED_CHILD_NODE_DEFINITIONS; +import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_NAMED_PROPERTY_DEFINITIONS; import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_RESIDUAL_CHILD_NODE_DEFINITIONS; +import java.util.Calendar; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -51,7 +63,10 @@ import com.google.common.collect.Iterato import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.TreeLocation; +import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.commons.PathUtils; +import org.apache.jackrabbit.oak.core.IdentifierManager; +import org.apache.jackrabbit.oak.plugins.memory.PropertyStates; import org.apache.jackrabbit.oak.util.TreeUtil; /** @@ -240,8 +255,7 @@ public class NodeDelegate extends ItemDe */ @CheckForNull public NodeDelegate addChild(String name, String typeName) - throws InvalidItemStateException, ConstraintViolationException, - NoSuchNodeTypeException { + throws RepositoryException { Tree tree = getTree(); if (tree.hasChild(name)) { return null; @@ -252,26 +266,12 @@ public class NodeDelegate extends ItemDe typeName = getDefaultChildType(typeRoot, tree, name); if (typeName == null) { throw new ConstraintViolationException( - "No default node type available for child node " + name); + "No default node type available for node " + + PathUtils.concat(tree.getPath(), name)); } } - Tree type = typeRoot.getChild(typeName); - if (type == null) { - throw new NoSuchNodeTypeException( - "Node type " + typeName + " does not exist"); - } else if (getBoolean(type, JCR_IS_ABSTRACT)) { - throw new ConstraintViolationException( - "Node type " + typeName + " is abstract"); - } else if (getBoolean(type, JCR_ISMIXIN)) { - throw new ConstraintViolationException( - "Node type " + typeName + " is a mixin type"); - } - Tree child = tree.addChild(name); - child.setProperty(JCR_PRIMARYTYPE, typeName, NAME); - if (getBoolean(type, JCR_HASORDERABLECHILDNODES)) { - child.setOrderableChildren(true); - } + Tree child = internalAddChild(tree, name, typeName, typeRoot); return new NodeDelegate(sessionDelegate, child); } @@ -295,6 +295,120 @@ public class NodeDelegate extends ItemDe //------------------------------------------------------------< internal >--- + private Tree internalAddChild( + Tree parent, String name, String typeName, Tree typeRoot) + throws RepositoryException { + Tree type = typeRoot.getChild(typeName); + if (type == null) { + throw new NoSuchNodeTypeException( + "Node type " + typeName + " does not exist"); + } else if (getBoolean(type, JCR_IS_ABSTRACT)) { + throw new ConstraintViolationException( + "Node type " + typeName + " is abstract"); + } else if (getBoolean(type, JCR_ISMIXIN)) { + throw new ConstraintViolationException( + "Node type " + typeName + " is a mixin type"); + } + + Tree child = parent.addChild(name); + child.setProperty(JCR_PRIMARYTYPE, typeName, NAME); + if (getBoolean(type, JCR_HASORDERABLECHILDNODES)) { + child.setOrderableChildren(true); + } + autoCreateItems(child, type, typeRoot); + return child; + } + + private void autoCreateItems(Tree tree, Tree type, Tree typeRoot) + throws RepositoryException { + // TODO: use a separate oak:autoCreatePropertyDefinitions + Tree properties = type.getChild(OAK_NAMED_PROPERTY_DEFINITIONS); + if (properties != null) { + for (Tree definitions : properties.getChildren()) { + String name = definitions.getName(); + if (name.equals("oak:primaryType") + || name.equals("oak:mixinTypes")) { + continue; + } else if (name.equals("oak:uuid")) { + name = JCR_UUID; + } + for (Tree definition : definitions.getChildren()) { + if (getBoolean(definition, JCR_AUTOCREATED)) { + if (!tree.hasProperty(name)) { + PropertyState property = + autoCreateProperty(name, definition); + if (property != null) { + tree.setProperty(property); + } else { + throw new RepositoryException( + "Unable to auto-create value for " + + PathUtils.concat(tree.getPath(), name)); + } + } + break; + } + } + } + } + + // TODO: use a separate oak:autoCreateChildNodeDefinitions + Tree childNodes = type.getChild(OAK_NAMED_CHILD_NODE_DEFINITIONS); + if (childNodes != null) { + for (Tree definitions : childNodes.getChildren()) { + String name = definitions.getName(); + for (Tree definition : definitions.getChildren()) { + if (getBoolean(definition, JCR_AUTOCREATED)) { + if (!tree.hasChild(name)) { + String typeName = + getName(definition, JCR_DEFAULTPRIMARYTYPE); + internalAddChild(tree, name, typeName, typeRoot); + } + break; + } + } + } + } + } + + private PropertyState autoCreateProperty(String name, Tree definition) { + if (JCR_UUID.equals(name)) { + String uuid = IdentifierManager.generateUUID(); + return PropertyStates.createProperty(name, uuid, STRING); + } else if (JCR_CREATED.equals(name)) { + long now = Calendar.getInstance().getTime().getTime(); + return PropertyStates.createProperty(name, now, DATE); + } else if (JCR_CREATEDBY.equals(name)) { + String userID = sessionDelegate.getAuthInfo().getUserID(); + if (userID != null) { + return PropertyStates.createProperty(name, userID, STRING); + } + } else if (JCR_LASTMODIFIED.equals(name)) { + long now = Calendar.getInstance().getTime().getTime(); + return PropertyStates.createProperty(name, now, DATE); + } else if (JCR_LASTMODIFIEDBY.equals(name)) { + String userID = sessionDelegate.getAuthInfo().getUserID(); + if (userID != null) { + return PropertyStates.createProperty(name, userID, STRING); + } + } + + // does the definition have a default value? + PropertyState values = definition.getProperty(JCR_DEFAULTVALUES); + if (values != null) { + Type type = values.getType(); + if (getBoolean(definition, JCR_MULTIPLE)) { + return PropertyStates.createProperty( + name, values.getValue(type), type); + } else { + type = type.getBaseType(); + return PropertyStates.createProperty( + name, values.getValue(type, 0), type); + } + } + + return null; + } + /** * Finds the default primary type for a new child node with the given name. *