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 mr...@apache.org on 2012/10/25 10:24:59 UTC

svn commit: r1402015 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ oak-jcr/src/test/resources/org...

Author: mreutegg
Date: Thu Oct 25 08:24:59 2012
New Revision: 1402015

URL: http://svn.apache.org/viewvc?rev=1402015&view=rev
Log:
OAK-249: Add support for auto created properties

Added:
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/AutoCreatedItemsTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeConstants.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/test/resources/org/apache/jackrabbit/oak/jcr/test_nodetypes.cnd

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeConstants.java?rev=1402015&r1=1402014&r2=1402015&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeConstants.java Thu Oct 25 08:24:59 2012
@@ -33,6 +33,14 @@ public interface NodeTypeConstants exten
     String JCR_AVAILABLE_QUERY_OPERATORS = "jcr:availableQueryOperators";
 
     /**
+     * Additinal name constants not present in JcrConstants
+     */
+    String JCR_CREATEDBY = "jcr:createdBy";
+    String JCR_LASTMODIFIEDBY = "jcr:lastModifiedBy";
+    String MIX_CREATED = "mix:created";
+    String MIX_LASTMODIFIED = "mix:lastModified";
+
+    /**
      * Merge conflict handling
      */
     String MIX_REP_MERGE_CONFLICT = "rep:MergeConflict";

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=1402015&r1=1402014&r2=1402015&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 Thu Oct 25 08:24:59 2012
@@ -50,6 +50,7 @@ import javax.jcr.nodetype.NoSuchNodeType
 import javax.jcr.nodetype.NodeDefinition;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.PropertyDefinition;
 import javax.jcr.version.Version;
 import javax.jcr.version.VersionHistory;
 
@@ -58,6 +59,8 @@ import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 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;
@@ -254,8 +257,9 @@ public class NodeImpl extends ItemImpl<N
                     throw new ItemExistsException();
                 }
 
-                Node childNode = new NodeImpl(added);
+                NodeImpl childNode = new NodeImpl(added);
                 childNode.setPrimaryType(ntName);
+                childNode.autoCreateItems();
                 return childNode;
             }
         });
@@ -929,7 +933,7 @@ public class NodeImpl extends ItemImpl<N
             public Void perform() throws RepositoryException {
                 // TODO: figure out the right place for this check
                 NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
-                NodeType nt = ntm.getNodeType(mixinName); // throws on not found
+                ntm.getNodeType(mixinName); // throws on not found
                 // TODO: END
 
                 PropertyDelegate mixins = dlg.getProperty(JcrConstants.JCR_MIXINTYPES);
@@ -948,10 +952,8 @@ public class NodeImpl extends ItemImpl<N
                     }
                 }
 
-                // TODO: hack -- make sure we assign a UUID
-                if (nodeModified && nt.isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
-                    Value uuid = sessionDelegate.getValueFactory().createValue(IdentifierManager.generateUUID());
-                    dlg.setProperty(JcrConstants.JCR_UUID, uuid);
+                if (nodeModified) {
+                    autoCreateItems();
                 }
                 return null;
             }
@@ -1378,6 +1380,90 @@ public class NodeImpl extends ItemImpl<N
         }
     }
 
+    private void autoCreateItems() throws RepositoryException {
+        Iterable<NodeType> types = getAllNodeTypes(this);
+        for (NodeType nt : types) {
+            for (PropertyDefinition pd : nt.getPropertyDefinitions()) {
+                if (pd.isAutoCreated() && dlg.getProperty(pd.getName()) == null) {
+                    if (pd.isMultiple()) {
+                        dlg.setProperty(pd.getName(), getAutoCreatedValues(pd));
+                    } else {
+                        dlg.setProperty(pd.getName(), getAutoCreatedValue(pd));
+                    }
+                }
+            }
+        }
+        for (NodeType nt : types) {
+            for (NodeDefinition nd : nt.getChildNodeDefinitions()) {
+                if (nd.isAutoCreated() && 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)) {
+            // jcr:createdBy property of a mix:created
+            if (NodeTypeConstants.MIX_CREATED.equals(declaringNT)) {
+                return getValueFactory().createValue(
+                        sessionDelegate.getAuthInfo().getUserID());
+            }
+        } 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)) {
+            // jcr:lastModifiedBy property of a mix:lastModified
+            if (NodeTypeConstants.MIX_LASTMODIFIED.equals(declaringNT)) {
+                return getValueFactory().createValue(
+                        sessionDelegate.getAuthInfo().getUserID());
+            }
+        }
+        // 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());
+    }
+
     // TODO: hack to filter for a subset of supported mixins for now
     // this allows only harmless mixin types so that other code like addMixin gets test coverage
     private boolean isSupportedMixinName(String mixinName) throws RepositoryException {

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/AutoCreatedItemsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/AutoCreatedItemsTest.java?rev=1402015&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/AutoCreatedItemsTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/AutoCreatedItemsTest.java Thu Oct 25 08:24:59 2012
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.jcr;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+import javax.jcr.Value;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * <code>AutoCreatedItemsTest</code> checks if auto-created nodes and properties
+ * are added correctly as defined in the node type definition.
+ */
+public class AutoCreatedItemsTest extends AbstractRepositoryTest {
+
+    @Test
+    public void autoCreatedItems() throws Exception {
+        Session s = getAdminSession();
+        new TestContentLoader().loadTestContent(s);
+        Node test = s.getRootNode().addNode("test", "test:autoCreate");
+        assertTrue(test.hasProperty("test:property"));
+        assertEquals("default value", test.getProperty("test:property").getString());
+        assertTrue(test.hasProperty("test:propertyMulti"));
+        assertArrayEquals(new Value[]{s.getValueFactory().createValue("value1"),
+                s.getValueFactory().createValue("value2")},
+                test.getProperty("test:propertyMulti").getValues());
+
+        assertTrue(test.hasNode("test:folder"));
+        Node folder = test.getNode("test:folder");
+        assertEquals("nt:folder", folder.getPrimaryNodeType().getName());
+        assertTrue(folder.hasProperty("jcr:created"));
+        assertTrue(folder.hasProperty("jcr:createdBy"));
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/AutoCreatedItemsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/AutoCreatedItemsTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/resources/org/apache/jackrabbit/oak/jcr/test_nodetypes.cnd
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/resources/org/apache/jackrabbit/oak/jcr/test_nodetypes.cnd?rev=1402015&r1=1402014&r2=1402015&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/resources/org/apache/jackrabbit/oak/jcr/test_nodetypes.cnd (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/resources/org/apache/jackrabbit/oak/jcr/test_nodetypes.cnd Thu Oct 25 08:24:59 2012
@@ -92,3 +92,8 @@
 
 [test:orderableFolder] > nt:folder orderable
   + * (nt:base) = test:orderableFolder
+
+[test:autoCreate]
+  - test:property (String) = 'default value' autocreated
+  - test:propertyMulti (String) = 'value1', 'value2' autocreated multiple
+  + test:folder (nt:folder) = nt:folder autocreated