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