jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1484469 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/nodetype/ test/java/org/apache/jackrabbit/oak/plugins/nodetype/
Date Mon, 20 May 2013 13:15:41 GMT
Author: jukka
Date: Mon May 20 13:15:41 2013
New Revision: 1484469

URL: http://svn.apache.org/r1484469
Log:
OAK-66: JCR Node Type Management

Improved tracking of effective types in the TypeEditor

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveType.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorProvider.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveType.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveType.java?rev=1484469&r1=1484468&r2=1484469&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveType.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveType.java
Mon May 20 13:15:41 2013
@@ -182,22 +182,24 @@ class EffectiveType {
      * types.
      *
      * @param nameWithIndex child node name, possibly with an SNS index
-     * @param nodeType effective types of the child node
-     * @return matching child node definition, or {@code null} if not found
+     * @param effective effective types of the child node
+     * @return {@code true} if there's a matching child node definition,
+     *         {@code false} otherwise
      */
-    @CheckForNull
-    NodeState getDefinition(String nameWithIndex, Iterable<String> nodeType) {
+    boolean isValidChildNode(String nameWithIndex, EffectiveType effective) {
         String nodeName = getNameWithoutIndex(nameWithIndex);
+        Set<String> typeNames = effective.getTypeNames();
 
         // Find matching named child node definition
         for (NodeState type : types) {
-            NodeState named = type.getChildNode("oak:namedChildNodeDefinitions");
-            NodeState definitions = named.getChildNode(nodeName);
+            NodeState definitions = type
+                    .getChildNode(OAK_NAMED_CHILD_NODE_DEFINITIONS)
+                    .getChildNode(nodeName);
 
-            for (String typeName : nodeType) {
+            for (String typeName : typeNames) {
                 NodeState definition = definitions.getChildNode(typeName);
                 if (definition.exists()) {
-                    return definition;
+                    return true;
                 }
             }
 
@@ -206,7 +208,7 @@ class EffectiveType {
             for (ChildNodeEntry entry : definitions.getChildNodeEntries()) {
                 NodeState definition = entry.getNodeState();
                 if (definition.getBoolean(JCR_MANDATORY)) {
-                    return definition;
+                    return false;
                 }
             }
 
@@ -218,18 +220,16 @@ class EffectiveType {
         // Find matching residual child node definition
         for (NodeState type : types) {
             NodeState residual =
-                    type.getChildNode("oak:residualChildNodeDefinitions");
-            if (residual.exists()) {
-                for (String typeName : nodeType) {
-                    NodeState definition = residual.getChildNode(typeName);
-                    if (definition.exists()) {
-                        return definition;
-                    }
+                    type.getChildNode(OAK_RESIDUAL_CHILD_NODE_DEFINITIONS);
+            for (String typeName : typeNames) {
+                NodeState definition = residual.getChildNode(typeName);
+                if (definition.exists()) {
+                    return true;
                 }
             }
         }
 
-        return null;
+        return false;
     }
 
     /**
@@ -292,15 +292,15 @@ class EffectiveType {
         NodeState type = types.getChildNode(primary);
         if (!type.exists()) {
             throw constraintViolation(
-                    11, path, "The primary type " + primary
+                    1, path, "The primary type " + primary
                     + " of child node " + name + " does not exist");
         } else if (type.getBoolean(JCR_ISMIXIN)) {
             throw constraintViolation(
-                    12, path, "Mixin type " + primary
+                    2, path, "Mixin type " + primary
                     + " used as the primary type of child node " + name);
         } else if (type.getBoolean(JCR_IS_ABSTRACT)) {
             throw constraintViolation(
-                    13, path, "Abstract type " + primary
+                    3, path, "Abstract type " + primary
                     + " used as the primary type of child node " + name);
         } else {
             list.add(type);
@@ -311,15 +311,15 @@ class EffectiveType {
             type = types.getChildNode(mixin);
             if (!type.exists()) {
                 throw constraintViolation(
-                        14, path, "The mixin type " + mixin
+                        5, path, "The mixin type " + mixin
                         + " of child node " + name + " does not exist");
             } else if (!type.getBoolean(JCR_ISMIXIN)) {
                 throw constraintViolation(
-                        15, path, "Primary type " + mixin
+                        6, path, "Primary type " + mixin
                         + " used as a mixin type of child node " + name);
             } else if (type.getBoolean(JCR_IS_ABSTRACT)) {
                 throw constraintViolation(
-                        16, path, "Abstract type " + mixin
+                        7, path, "Abstract type " + mixin
                         + " used as a mixin type of child node " + name);
             } else {
                 list.add(type);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java?rev=1484469&r1=1484468&r2=1484469&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
Mon May 20 13:15:41 2013
@@ -16,10 +16,14 @@
  */
 package org.apache.jackrabbit.oak.plugins.nodetype;
 
+import java.util.List;
+
 import javax.jcr.PropertyType;
 import javax.jcr.Value;
 
 import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
@@ -30,6 +34,7 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.JcrConstants.JCR_ISMIXIN;
 import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
 import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
 import static org.apache.jackrabbit.JcrConstants.JCR_REQUIREDTYPE;
@@ -40,7 +45,9 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.api.Type.STRING;
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
 import static org.apache.jackrabbit.oak.core.IdentifierManager.isValidUUID;
+import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
 import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;
+import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_IS_ABSTRACT;
 import static org.apache.jackrabbit.oak.plugins.nodetype.constraint.Constraints.valueConstraint;
 
 /**
@@ -64,24 +71,39 @@ class TypeEditor extends DefaultEditor {
 
     private final NodeBuilder builder;
 
-    TypeEditor(NodeState types, EffectiveType effective, NodeBuilder builder) {
+    TypeEditor(
+            NodeState types,
+            String primary, Iterable<String> mixins, NodeBuilder builder)
+            throws CommitFailedException {
         this.parent = null;
         this.nodeName = null;
         this.types = checkNotNull(types);
-        this.effective = checkNotNull(effective);
+        this.effective = getEffectiveType(primary, mixins);
         this.builder = checkNotNull(builder);
     }
 
     private TypeEditor(
             TypeEditor parent, String name,
-            EffectiveType effective, NodeBuilder builder) {
+            String primary, Iterable<String> mixins, NodeBuilder builder)
+            throws CommitFailedException {
         this.parent = checkNotNull(parent);
         this.nodeName = checkNotNull(name);
         this.types = parent.types;
-        this.effective = checkNotNull(effective);
+        this.effective = getEffectiveType(primary, mixins);
         this.builder = checkNotNull(builder);
     }
 
+    /**
+     * Test constructor.
+     */
+    TypeEditor(EffectiveType effective) {
+        this.parent = null;
+        this.nodeName = null;
+        this.types = EMPTY_NODE;
+        this.effective = checkNotNull(effective);
+        this.builder = EMPTY_NODE.builder();
+    }
+
     private CommitFailedException constraintViolation(
             int code, String message) {
         return effective.constraintViolation(code, getPath(), message);
@@ -98,12 +120,6 @@ class TypeEditor extends DefaultEditor {
     }
 
     @Override
-    public void leave(NodeState before, NodeState after)
-            throws CommitFailedException {
-        // TODO: add any auto-created items that are still missing
-    }
-
-    @Override
     public void propertyAdded(PropertyState after)
             throws CommitFailedException {
         propertyChanged(null, after);
@@ -144,6 +160,8 @@ class TypeEditor extends DefaultEditor {
             throws CommitFailedException {
         TypeEditor editor = childNodeChanged(name, MISSING_NODE, after);
 
+        // TODO: add any auto-created items that are still missing
+
         // verify the presence of all mandatory items
         for (String property : editor.effective.getMandatoryProperties()) {
             if (!after.hasProperty(property)) {
@@ -167,9 +185,10 @@ class TypeEditor extends DefaultEditor {
     public TypeEditor childNodeChanged(
             String name, NodeState before, NodeState after)
             throws CommitFailedException {
-        NodeBuilder childBuilder = builder.getChildNode(name);
-
         String primary = after.getName(JCR_PRIMARYTYPE);
+        Iterable<String> mixins = after.getNames(JCR_MIXINTYPES);
+
+        NodeBuilder childBuilder = builder.getChildNode(name);
         if (primary == null) {
             // no primary type defined, find and apply a default type
             primary = effective.getDefaultType(name);
@@ -177,22 +196,20 @@ class TypeEditor extends DefaultEditor {
                 builder.setProperty(JCR_PRIMARYTYPE, primary, NAME);
             } else {
                 throw constraintViolation(
-                        5, "No default primary type available "
+                        4, "No default primary type available "
                         + " for child node " + name);
             }
         }
 
-        EffectiveType childType = effective.computeEffectiveType(
-                types, getPath(), // TODO: compute path only on demand
-                name, primary, after.getNames(JCR_MIXINTYPES));
-
-        if (effective.getDefinition(name, childType.getTypeNames()) == null) {
+        TypeEditor editor =
+                new TypeEditor(this, name, primary, mixins, childBuilder);
+        if (!effective.isValidChildNode(name, editor.effective)) {
             throw constraintViolation(
                     1, "No matching definition found for child node " + name
-                    + " with effective type " + childType.getTypeNames());
+                    + " with effective type " + editor.effective);
         }
 
-        return new TypeEditor(this, name, childType, childBuilder);
+        return editor;
     }
 
     @Override
@@ -208,6 +225,45 @@ class TypeEditor extends DefaultEditor {
 
     //-----------------------------------------------------------< private >--
 
+    private EffectiveType getEffectiveType(
+            String primary, Iterable<String> mixins)
+            throws CommitFailedException {
+        List<NodeState> list = Lists.newArrayList();
+
+        NodeState type = types.getChildNode(primary);
+        if (!type.exists()) {
+            throw constraintViolation(
+                    1, "The primary type " + primary + " does not exist");
+        } else if (type.getBoolean(JCR_ISMIXIN)) {
+            throw constraintViolation(
+                    2, "Mixin type " + primary + " used as the primary type");
+        } else if (type.getBoolean(JCR_IS_ABSTRACT)) {
+            throw constraintViolation(
+                    3, "Abstract type " + primary + " used as the primary type");
+        } else {
+            list.add(type);
+        }
+
+        // mixin types
+        for (String mixin : mixins) {
+            type = types.getChildNode(mixin);
+            if (!type.exists()) {
+                throw constraintViolation(
+                        5, "The mixin type " + mixin + " does not exist");
+            } else if (!type.getBoolean(JCR_ISMIXIN)) {
+                throw constraintViolation(
+                        6, "Primary type " + mixin + " used as a mixin type");
+            } else if (type.getBoolean(JCR_IS_ABSTRACT)) {
+                throw constraintViolation(
+                        7, "Abstract type " + mixin + " used as a mixin type");
+            } else {
+                list.add(type);
+            }
+        }
+
+        return new EffectiveType(list);
+    }
+
     private void checkValueConstraints(
             NodeState definition, PropertyState property)
             throws CommitFailedException {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorProvider.java?rev=1484469&r1=1484468&r2=1484469&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorProvider.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorProvider.java
Mon May 20 13:15:41 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.oak.plugins.nodetype;
 
-import static java.util.Arrays.asList;
 import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
 import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
 import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
@@ -45,17 +44,16 @@ public class TypeEditorProvider implemen
         if (types.exists()) {
 
             String primary = after.getName(JCR_PRIMARYTYPE);
+            Iterable<String> mixins = after.getNames(JCR_MIXINTYPES);
+
             if (primary == null) {
                 // no primary type on the root node, set the hardcoded default
                 primary = "rep:root";
                 builder.setProperty(JCR_PRIMARYTYPE, primary, NAME);
             }
-            NodeState unstructured = types.getChildNode("oak:unstructured");
-            EffectiveType parent = new EffectiveType(asList(unstructured));
-            EffectiveType effective = parent.computeEffectiveType(
-                    types, "/", null, primary, after.getNames(JCR_MIXINTYPES));
 
-            return new VisibleEditor(new TypeEditor(types, effective, builder));
+            return new VisibleEditor(
+                    new TypeEditor(types, primary, mixins, builder));
         } else {
             return null;
         }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java?rev=1484469&r1=1484468&r2=1484469&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java
Mon May 20 13:15:41 2013
@@ -64,8 +64,7 @@ public class TypeEditorTest {
 
         replay(effective);
 
-        TypeEditor editor =
-                new TypeEditor(EMPTY_NODE, effective, EMPTY_NODE.builder());
+        TypeEditor editor = new TypeEditor(effective);
         editor.propertyDeleted(PropertyStates.createProperty("mandatory", ""));
     }
 
@@ -79,8 +78,7 @@ public class TypeEditorTest {
 
         replay(effective);
 
-        TypeEditor editor =
-                new TypeEditor(EMPTY_NODE, effective, EMPTY_NODE.builder());
+        TypeEditor editor = new TypeEditor(effective);
         editor.propertyDeleted(PropertyStates.createProperty("mandatory", ""));
     }
 
@@ -91,8 +89,7 @@ public class TypeEditorTest {
 
         replay(effective);
 
-        TypeEditor editor =
-                new TypeEditor(EMPTY_NODE, effective, EMPTY_NODE.builder());
+        TypeEditor editor = new TypeEditor(effective);
         editor.childNodeDeleted("mandatory", EMPTY_NODE);
     }
 
@@ -106,8 +103,7 @@ public class TypeEditorTest {
 
         replay(effective);
 
-        TypeEditor editor =
-                new TypeEditor(EMPTY_NODE, effective, EMPTY_NODE.builder());
+        TypeEditor editor = new TypeEditor(effective);
         editor.childNodeDeleted("mandatory", EMPTY_NODE);
     }
 }



Mime
View raw message