Author: rombert Date: Sun Oct 12 22:26:20 2014 New Revision: 1631261 URL: http://svn.apache.org/r1631261 Log: SLING-4035 - Changing the jcr primary type does not work if properties are added
Change the jcr primary type earlier in the AddOrUpdateNodeCommand . Added: sling/trunk/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/folder.cnd Modified: sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandTest.java sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java Modified: sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandTest.java URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandTest.java?rev=1631261&r1=1631260&r2=1631261&view=diff ============================================================================== --- sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandTest.java (original) +++ sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandTest.java Sun Oct 12 22:26:20 2014 @@ -20,6 +20,8 @@ import static org.hamcrest.CoreMatchers. import static org.junit.Assert.assertThat; import java.io.File; +import java.io.InputStream; +import java.io.InputStreamReader; import javax.jcr.Node; import javax.jcr.Property; @@ -29,6 +31,8 @@ import javax.jcr.SimpleCredentials; import javax.jcr.Value; import javax.jcr.nodetype.NodeType; +import org.apache.commons.io.IOUtils; +import org.apache.jackrabbit.commons.cnd.CndImporter; import org.apache.jackrabbit.core.TransientRepository; import org.apache.sling.ide.log.Logger; import org.apache.sling.ide.transport.ResourceProxy; @@ -122,6 +126,78 @@ public class AddOrUpdateNodeCommandTest doPropertyChangeTest(new String[] { "Title", "Title 2" }, "Title"); } + @Test + public void changeNtFolderToSlingFolderWithAddedProperty() throws Exception { + + File out = new File(new File("target"), "jackrabbit"); + TransientRepository repo = new TransientRepository(new File(out, "repository.xml"), new File(out, "repository")); + SimpleCredentials credentials = new SimpleCredentials("admin", "admin".toCharArray()); + Session session = repo.login(credentials); + + InputStream cndInput = getClass().getResourceAsStream("folder.cnd"); + CndImporter.registerNodeTypes(new InputStreamReader(cndInput), session); + + try { + session.getRootNode().addNode("content", "nt:folder"); + + session.save(); + + ResourceProxy resource = newResource("/content", "sling:Folder"); + resource.getProperties().put("newProperty", "some/value"); + + AddOrUpdateNodeCommand cmd = new AddOrUpdateNodeCommand(repo, credentials, null, resource, logger); + cmd.execute().get(); + + session.refresh(false); + + Node content = session.getRootNode().getNode("content"); + assertThat(content.getPrimaryNodeType().getName(), equalTo("sling:Folder")); + + } finally { + session.removeItem("/content"); + session.save(); + session.logout(); + + IOUtils.closeQuietly(cndInput); + } + } + + @Test + public void changeSlingFolderToNtFolderWithExistingProperty() throws Exception { + + File out = new File(new File("target"), "jackrabbit"); + TransientRepository repo = new TransientRepository(new File(out, "repository.xml"), new File(out, "repository")); + SimpleCredentials credentials = new SimpleCredentials("admin", "admin".toCharArray()); + Session session = repo.login(credentials); + + InputStream cndInput = getClass().getResourceAsStream("folder.cnd"); + CndImporter.registerNodeTypes(new InputStreamReader(cndInput), session); + + try { + Node content = session.getRootNode().addNode("content", "sling:Folder"); + content.setProperty("newProperty", "some/value"); + + session.save(); + + ResourceProxy resource = newResource("/content", "nt:folder"); + + AddOrUpdateNodeCommand cmd = new AddOrUpdateNodeCommand(repo, credentials, null, resource, logger); + cmd.execute().get(); + + session.refresh(false); + + content = session.getRootNode().getNode("content"); + assertThat(content.getPrimaryNodeType().getName(), equalTo("nt:folder")); + + } finally { + session.removeItem("/content"); + session.save(); + session.logout(); + + IOUtils.closeQuietly(cndInput); + } + } + private ResourceProxy newResource(String path, String primaryType) { ResourceProxy resource = new ResourceProxy(path); Added: sling/trunk/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/folder.cnd URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/folder.cnd?rev=1631261&view=auto ============================================================================== --- sling/trunk/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/folder.cnd (added) +++ sling/trunk/tooling/ide/impl-vlt-test/src/test/resources/org/apache/sling/ide/impl/vlt/folder.cnd Sun Oct 12 22:26:20 2014 @@ -0,0 +1,46 @@ +// +// 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. +// + +<sling = 'http://sling.apache.org/jcr/sling/1.0'> + +//----------------------------------------------------------------------------- +// Node type to be used as a replacement for nt:folder: it can be used +// as a child of nt:folder and allows to add unstructured content +// (See SLING-663) +[sling:Folder] > nt:folder + - * (undefined) multiple + - * (undefined) + + * (nt:base) = sling:Folder version + + +//----------------------------------------------------------------------------- +// Mixin node type to turn any node into an nt:hierarchyNode to place +// below any nt:folder (or extension thereof such as sling:Folder) +// (See SLING-663) +[sling:HierarchyNode] > nt:hierarchyNode + mixin + + +//----------------------------------------------------------------------------- +// Node type extending sling:Folder supporting the creation of folder +// structured with child node ordering. +// (See SLING-663) +[sling:OrderedFolder] > sling:Folder + orderable + + * (nt:base) = sling:OrderedFolder version Modified: sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java?rev=1631261&r1=1631260&r2=1631261&view=diff ============================================================================== --- sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java (original) +++ sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java Sun Oct 12 22:26:20 2014 @@ -64,7 +64,6 @@ public class AddOrUpdateNodeCommand exte private ResourceProxy resource; private FileInfo fileInfo; - private boolean primaryTypeHasChanged; public AddOrUpdateNodeCommand(Repository jcrRepo, Credentials credentials, FileInfo fileInfo, ResourceProxy resource, Logger logger) { @@ -103,13 +102,6 @@ public class AddOrUpdateNodeCommand exte for (ResourceProxy child : resource.getCoveredChildren()) { update(child, session); } - - // save the changes so that the primary node type is propagated - // however, we can't do that too early, since required properties might not be set - // so we save right before checking for orderable child nodes - if (primaryTypeHasChanged) { - session.save(); - } } private void processDeletedNodes(Node node, ResourceProxy resource2) throws RepositoryException { @@ -199,10 +191,17 @@ public class AddOrUpdateNodeCommand exte updateMixins(node, mixinTypes); } + // remove old properties first + // this supports the scenario where the node type is changed to a less permissive one + for (String propertyToRemove : propertiesToRemove) { + node.getProperty(propertyToRemove).remove(); + getLogger().trace("Removed property {0} from node at {1}", propertyToRemove, node.getPath()); + } + String primaryType = (String) resource.getProperties().get(JcrConstants.JCR_PRIMARYTYPE); if (!node.getPrimaryNodeType().getName().equals(primaryType) && node.getDepth() != 0) { node.setPrimaryType(primaryType); - primaryTypeHasChanged = true; + session.save(); getLogger().trace("Set new primary type {0} for node at {1}", primaryType, node.getPath()); } @@ -289,12 +288,6 @@ public class AddOrUpdateNodeCommand exte + propertyName + "' with value '" + propertyValue + "'"); } } - - for (String propertyToRemove : propertiesToRemove) { - node.getProperty(propertyToRemove).remove(); - getLogger().trace("Removed property {0} from node at {1}", propertyToRemove, node.getPath()); - } - } private void ensurePropertyDefinitionMatchers(Property property, int expectedType, boolean expectedMultiplicity)