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 ju...@apache.org on 2013/04/26 10:24:12 UTC

svn commit: r1476096 - in /jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr: NodeImpl.java delegate/NodeDelegate.java

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<T extends NodeDele
                     throw new ItemExistsException();
                 }
 
-                NodeImpl<?> childNode = new NodeImpl<NodeDelegate>(added, sessionContext);
-                childNode.autoCreateItems();
-                return childNode;
+                return new NodeImpl<NodeDelegate>(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.
      *