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 15:13:25 UTC

svn commit: r1476180 - 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 13:13:24 2013
New Revision: 1476180

URL: http://svn.apache.org/r1476180
Log:
OAK-702: Optimize access to node type information

Streamline addMixin()

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=1476180&r1=1476179&r2=1476180&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 13:13:24 2013
@@ -21,7 +21,6 @@ import java.math.BigDecimal;
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Set;
 import javax.annotation.Nonnull;
 import javax.jcr.AccessDeniedException;
@@ -59,7 +58,6 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.commons.ItemNameMatcher;
 import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
@@ -77,8 +75,6 @@ import org.apache.jackrabbit.oak.jcr.del
 import org.apache.jackrabbit.oak.jcr.delegate.PropertyDelegate;
 import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
 import org.apache.jackrabbit.oak.plugins.nodetype.EffectiveNodeType;
-import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
-import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
 import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
 import org.apache.jackrabbit.oak.util.TODO;
 import org.apache.jackrabbit.value.ValueHelper;
@@ -863,39 +859,12 @@ public class NodeImpl<T extends NodeDele
     }
 
     @Override
-    public void addMixin(final String mixinName) throws RepositoryException {
+    public void addMixin(String mixinName) throws RepositoryException {
+        final String oakMixinName = getOakName(mixinName);
         perform(new ItemWriteOperation<Void>() {
             @Override
             public Void perform() throws RepositoryException {
-                // TODO: figure out the right place for this check
-                getNodeTypeManager().getNodeType(mixinName); // throws on not found
-                // TODO: END
-
-                if (isNodeType(mixinName)) {
-                    return null;
-                }
-
-                PropertyDelegate mixins = dlg.getPropertyOrNull(JcrConstants.JCR_MIXINTYPES);
-                Value value = getValueFactory().createValue(mixinName, PropertyType.NAME);
-
-                boolean nodeModified = false;
-                if (mixins == null) {
-                    nodeModified = true;
-                    dlg.setProperty(PropertyStates.createProperty(
-                            JcrConstants.JCR_MIXINTYPES, Collections.singletonList(value)));
-                } else {
-                    PropertyState property = mixins.getMultiState();
-                    List<Value> values = ValueFactoryImpl.createValues(property, sessionContext);
-                    if (!values.contains(value)) {
-                        values.add(value);
-                        nodeModified = true;
-                        dlg.setProperty(PropertyStates.createProperty(JcrConstants.JCR_MIXINTYPES, values));
-                    }
-                }
-
-                if (nodeModified) {
-                    autoCreateItems();
-                }
+                dlg.addMixin(oakMixinName);
                 return null;
             }
         });
@@ -1335,88 +1304,6 @@ public class NodeImpl<T extends NodeDele
                 });
     }
 
-    private void autoCreateItems() throws RepositoryException {
-        EffectiveNodeType effective = getEffectiveNodeType();
-        for (PropertyDefinition pd : effective.getAutoCreatePropertyDefinitions()) {
-            if (dlg.getPropertyOrNull(pd.getName()) == null) {
-                if (pd.isMultiple()) {
-                    dlg.setProperty(PropertyStates.createProperty(pd.getName(), getAutoCreatedValues(pd)));
-                } else {
-                    dlg.setProperty(PropertyStates.createProperty(pd.getName(), getAutoCreatedValue(pd)));
-                }
-            }
-        }
-        for (NodeDefinition nd : effective.getAutoCreateNodeDefinitions()) {
-            if (dlg.getChild(nd.getName()) == null) {
-                autoCreateNode(nd);
-            }
-        }
-    }
-
-    private Value getAutoCreatedValue(PropertyDefinition definition)
-            throws RepositoryException {
-        String name = definition.getName();
-        String declaringNT = definition.getDeclaringNodeType().getName();
-
-        if (NodeTypeConstants.JCR_UUID.equals(name)) {
-            // jcr:uuid property of the mix:referenceable node type
-            if (NodeTypeConstants.MIX_REFERENCEABLE.equals(declaringNT)) {
-                return getValueFactory().createValue(IdentifierManager.generateUUID());
-            }
-        } else if (NodeTypeConstants.JCR_CREATED.equals(name)) {
-            // jcr:created property of a version or a mix:created
-            if (NodeTypeConstants.MIX_CREATED.equals(declaringNT)
-                    || NodeTypeConstants.NT_VERSION.equals(declaringNT)) {
-                return getValueFactory().createValue(Calendar.getInstance());
-            }
-        } else if (NodeTypeConstants.JCR_CREATEDBY.equals(name)) {
-            String userID = sessionDelegate.getAuthInfo().getUserID();
-            // jcr:createdBy property of a mix:created
-            if (userID != null
-                    && NodeTypeConstants.MIX_CREATED.equals(declaringNT)) {
-                return getValueFactory().createValue(userID);
-            }
-        } else if (NodeTypeConstants.JCR_LASTMODIFIED.equals(name)) {
-            // jcr:lastModified property of a mix:lastModified
-            if (NodeTypeConstants.MIX_LASTMODIFIED.equals(declaringNT)) {
-                return getValueFactory().createValue(Calendar.getInstance());
-            }
-        } else if (NodeTypeConstants.JCR_LASTMODIFIEDBY.equals(name)) {
-            String userID = sessionDelegate.getAuthInfo().getUserID();
-            // jcr:lastModifiedBy property of a mix:lastModified
-            if (userID != null
-                    && NodeTypeConstants.MIX_LASTMODIFIED.equals(declaringNT)) {
-                return getValueFactory().createValue(userID);
-            }
-        }
-        // does the definition have a default value?
-        if (definition.getDefaultValues() != null) {
-            Value[] values = definition.getDefaultValues();
-            if (values.length > 0) {
-                return values[0];
-            }
-        }
-        throw new RepositoryException("Unable to auto-create value for " +
-                PathUtils.concat(getPath(), name));
-    }
-
-    private Iterable<Value> getAutoCreatedValues(PropertyDefinition definition)
-            throws RepositoryException {
-        String name = definition.getName();
-
-        // default values?
-        if (definition.getDefaultValues() != null) {
-            return Lists.newArrayList(definition.getDefaultValues());
-        }
-        throw new RepositoryException("Unable to auto-create value for " +
-                PathUtils.concat(getPath(), name));
-    }
-
-    private void autoCreateNode(NodeDefinition definition)
-            throws RepositoryException {
-        addNode(definition.getName(), definition.getDefaultPrimaryTypeName());
-    }
-
     private void checkValidWorkspace(String workspaceName) throws RepositoryException {
         Workspace workspace = sessionContext.getWorkspace();
         for (String wn : workspace.getAccessibleWorkspaceNames()) {

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=1476180&r1=1476179&r2=1476180&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 13:13:24 2013
@@ -16,7 +16,9 @@
  */
 package org.apache.jackrabbit.oak.jcr.delegate;
 
+import static com.google.common.collect.Iterables.contains;
 import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Sets.newHashSet;
 import static java.util.Collections.emptyList;
 import static org.apache.jackrabbit.JcrConstants.JCR_AUTOCREATED;
 import static org.apache.jackrabbit.JcrConstants.JCR_CREATED;
@@ -38,14 +40,17 @@ import static org.apache.jackrabbit.oak.
 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_MIXIN_SUBTYPES;
 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_PRIMARY_SUBTYPES;
 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;
+import java.util.Set;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -224,6 +229,43 @@ public class NodeDelegate extends ItemDe
         }
     }
 
+    public void addMixin(String typeName) throws RepositoryException {
+        Tree typeRoot = sessionDelegate.getRoot().getTree(NODE_TYPES_PATH);
+
+        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 not a mixin type");
+        }
+
+        Tree tree = getTree();
+        List<String> mixins = newArrayList();
+
+        String primary = getName(tree, JCR_PRIMARYTYPE);
+        if (primary != null
+                && contains(getNames(type, OAK_PRIMARY_SUBTYPES), primary)) {
+            return;
+        }
+
+        Set<String> submixins = newHashSet(getNames(type, OAK_MIXIN_SUBTYPES));
+        for (String mixin : getNames(tree, JCR_MIXINTYPES)) {
+            if (typeName.equals(mixin) || submixins.contains(mixin)) {
+                return;
+            }
+            mixins.add(mixin);
+        }
+
+        mixins.add(typeName);
+        tree.setProperty(JCR_MIXINTYPES, mixins, NAMES);
+        autoCreateItems(tree, type, typeRoot);
+    }
+
     /**
      * Set a property
      *
@@ -399,7 +441,7 @@ public class NodeDelegate extends ItemDe
             if (getBoolean(definition, JCR_MULTIPLE)) {
                 return PropertyStates.createProperty(
                         name, values.getValue(type), type);
-            } else {
+            } else if (values.count() > 0) {
                 type = type.getBaseType();
                 return PropertyStates.createProperty(
                         name, values.getValue(type, 0), type);