You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2014/05/12 15:12:01 UTC

svn commit: r1593959 - in /sling/trunk/tooling/ide: eclipse-test/src/org/apache/sling/ide/test/impl/ impl-vlt/src/org/apache/sling/ide/impl/vlt/

Author: rombert
Date: Mon May 12 13:12:01 2014
New Revision: 1593959

URL: http://svn.apache.org/r1593959
Log:
SLING-3116 - Node structures serialized to a .content.xml file do not
propagate deletions

React when nodes are deleted from a .content.xml file.

Added:
    sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/content-nested-structure-deleted-node.xml   (with props)
Modified:
    sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/JcrFullCoverageAggregatesDeploymentTest.java
    sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java

Modified: sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/JcrFullCoverageAggregatesDeploymentTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/JcrFullCoverageAggregatesDeploymentTest.java?rev=1593959&r1=1593958&r2=1593959&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/JcrFullCoverageAggregatesDeploymentTest.java (original)
+++ sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/JcrFullCoverageAggregatesDeploymentTest.java Mon May 12 13:12:01 2014
@@ -108,6 +108,64 @@ public class JcrFullCoverageAggregatesDe
         }, postConditions);
     }
 
+    @Test
+    public void deleteNodeFromNestedFullCoverageAggreate() throws Exception {
+
+        wstServer.waitForServerToStart();
+
+        // create faceted project
+        IProject contentProject = projectRule.getProject();
+
+        ProjectAdapter project = new ProjectAdapter(contentProject);
+        project.addNatures("org.eclipse.wst.common.project.facet.core.nature");
+
+        // create .content.xml structure
+        InputStream contentXml = getClass().getResourceAsStream("content-nested-structure.xml");
+        try {
+            project.createOrUpdateFile(Path.fromPortableString("jcr_root/content/test-root/en.xml"), contentXml);
+        } finally {
+            IOUtils.closeQuietly(contentXml);
+        }
+
+        // install content facet
+        project.installFacet("sling.content", "1.0");
+
+        ServerAdapter server = new ServerAdapter(wstServer.getServer());
+        server.installModule(contentProject);
+
+        Matcher postConditions = allOf(hasPath("/content/test-root/en"), hasPrimaryType("sling:Folder"),
+                hasMixinTypes("mix:language"), hasChildrenCount(3));
+
+        final RepositoryAccessor repo = new RepositoryAccessor(config);
+        Poller poller = new Poller();
+        poller.pollUntil(new Callable<Node>() {
+            @Override
+            public Node call() throws RepositoryException {
+                return repo.getNode("/content/test-root/en");
+
+            }
+        }, postConditions);
+
+        // update .content.xml structure
+        InputStream updatedContentXml = getClass().getResourceAsStream("content-nested-structure-deleted-node.xml");
+        try {
+            project.createOrUpdateFile(Path.fromPortableString("jcr_root/content/test-root/en.xml"), updatedContentXml);
+        } finally {
+            IOUtils.closeQuietly(updatedContentXml);
+        }
+
+        // poll until we only have 2 child nodes left
+        postConditions = allOf(hasPath("/content/test-root/en"), hasPrimaryType("sling:Folder"),
+                hasMixinTypes("mix:language"), hasChildrenCount(2));
+        poller.pollUntil(new Callable<Node>() {
+            @Override
+            public Node call() throws RepositoryException {
+                return repo.getNode("/content/test-root/en");
+
+            }
+        }, postConditions);
+    }
+
     @After
     public void cleanup() throws Exception {
         new RepositoryAccessor(config).tryDeleteResource("/content/test-root");

Added: sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/content-nested-structure-deleted-node.xml
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/content-nested-structure-deleted-node.xml?rev=1593959&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/content-nested-structure-deleted-node.xml (added)
+++ sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/content-nested-structure-deleted-node.xml Mon May 12 13:12:01 2014
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:vlt="http://www.day.com/jcr/vault/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:mixinTypes="[mix:language]"
+    jcr:primaryType="sling:Folder"
+    jcr:language="en">
+    <message
+        jcr:primaryType="nt:unstructured"
+        sling:key="message"
+        sling:value="Message">
+    </message>
+    <warning
+        jcr:primaryType="nt:unstructured"
+        sling:key="warning"
+        sling:value="Warning">
+    </warning>
+</jcr:root>
\ No newline at end of file

Propchange: sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/content-nested-structure-deleted-node.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/content-nested-structure-deleted-node.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

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=1593959&r1=1593958&r2=1593959&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 Mon May 12 13:12:01 2014
@@ -31,6 +31,7 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -40,6 +41,7 @@ import java.util.UUID;
 import javax.jcr.Binary;
 import javax.jcr.Credentials;
 import javax.jcr.Node;
+import javax.jcr.NodeIterator;
 import javax.jcr.Property;
 import javax.jcr.PropertyIterator;
 import javax.jcr.PropertyType;
@@ -91,18 +93,58 @@ public class AddOrUpdateNodeCommand exte
         }
 
         updateNode(node, resource);
+        processDeletedNodes(node, resource);
+        for (ResourceProxy child : getCoveredChildren(resource)) {
+            update(child, session);
+        }
+
+        // TODO - does not handle deletion of nodes which no longer have a matching resource
+	}
+
+    private void processDeletedNodes(Node node, ResourceProxy resource2) throws RepositoryException {
+
+        // TODO - we probably don't support SNS here ( and in other places as well )
+
+        // gather a list of existing paths for all covered children
+        // all nodes which are not found in these paths will be deleted
+        List<ResourceProxy> coveredResourceChildren = getCoveredChildren(resource2);
+        Map<String, ResourceProxy> resourceChildrenPaths = new HashMap<String, ResourceProxy>(
+                coveredResourceChildren.size());
+        for (ResourceProxy coveredChild : coveredResourceChildren) {
+            resourceChildrenPaths.put(coveredChild.getPath(), coveredChild);
+        }
+
+        for (NodeIterator it = node.getNodes(); it.hasNext();) {
+
+            // TODO - recurse
+            Node child = it.nextNode();
+            if (resourceChildrenPaths.containsKey(child.getPath())) {
+                System.out.println("Node at path " + child.getPath() + " lives on.");
+                processDeletedNodes(child, resourceChildrenPaths.get(child.getPath()));
+                continue;
+            }
+
+            System.out.println("Removing node at path " + child.getPath());
+            child.remove();
+        }
+    }
+
+    private List<ResourceProxy> getCoveredChildren(ResourceProxy resource) {
+        // TODO - this is a workaround for partial coverage nodes being sent here
+        // when a .content.xml file with partial coverage is added here, the children are listed with no properties
+        // and get all their properties deleted
+
+        List<ResourceProxy> coveredChildren = new ArrayList<ResourceProxy>();
         for (ResourceProxy child : resource.getChildren()) {
-            // TODO - this is a workaround for partial coverage nodes being sent here
-            // when a .content.xml file with partial coverage is added here, the children are listed with no properties
-            // and get all their properties deleted
             if (child.getProperties().isEmpty()) {
                 continue;
             }
-            update(child, session);
+
+            coveredChildren.add(child);
         }
 
-        // TODO - does not handle deletion of nodes which no longer have a matching resource
-	}
+        return coveredChildren;
+    }
 
     private Node createNode(ResourceProxy resource, Session session) throws RepositoryException, FileNotFoundException {