You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by np...@apache.org on 2018/05/30 13:00:48 UTC

[sling-org-apache-sling-pipes] branch master updated: SLING-7693 add JCR path creation when node type

This is an automated email from the ASF dual-hosted git repository.

npeltier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-pipes.git


The following commit(s) were added to refs/heads/master by this push:
     new be80b01  SLING-7693 add JCR path creation when node type
be80b01 is described below

commit be80b019bf2433aeca6cbc897e606e68941d9f0a
Author: Nicolas Peltier <pe...@gmail.com>
AuthorDate: Wed May 30 14:57:18 2018 +0200

    SLING-7693 add JCR path creation when node type
    
    - added unit tests,
    - added unit tests for autosave for which i had to fix jcr_mock (SLING-7692)
---
 pom.xml                                            |  4 +-
 .../org/apache/sling/pipes/internal/PathPipe.java  | 64 ++++++++++++++++++++--
 .../apache/sling/pipes/internal/PathPipeTest.java  | 44 +++++++++++++--
 3 files changed, 101 insertions(+), 11 deletions(-)

diff --git a/pom.xml b/pom.xml
index b09f9db..fa138d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -244,8 +244,8 @@
     </dependency>
     <dependency>
       <groupId>org.apache.sling</groupId>
-      <artifactId>org.apache.sling.testing.sling-mock-oak</artifactId>
-      <version>2.0.2</version>
+      <artifactId>org.apache.sling.testing.jcr-mock</artifactId>
+      <version>1.3.3-SNAPSHOT</version>
       <scope>test</scope>
     </dependency>
     <dependency>
diff --git a/src/main/java/org/apache/sling/pipes/internal/PathPipe.java b/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
index bbe692d..1f06ab3 100644
--- a/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sling.pipes.internal;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceUtil;
@@ -24,9 +25,12 @@ import org.apache.sling.pipes.Plumber;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.script.ScriptException;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.StringTokenizer;
 
 import static org.apache.sling.jcr.resource.JcrResourceConstants.NT_SLING_FOLDER;
 
@@ -42,21 +46,26 @@ import static org.apache.sling.jcr.resource.JcrResourceConstants.NT_SLING_FOLDER
 public class PathPipe extends BasePipe {
 
     public static final String RESOURCE_TYPE = RT_PREFIX + "path";
-    public static final String PN_RESOURCETYPE = "nodeType";
+    public static final String PN_RESOURCETYPE = "resourceType";
+    public static final String PN_NODETYPE = "nodeType";
     public static final String PN_INTERMEDIATE = "intermediateType";
     public static final String PN_AUTOSAVE = "autosave";
     public static final String SLASH = "/";
 
     String resourceType;
+    String nodeType;
     String intermediateType;
     boolean autosave;
+    boolean jcr;
 
     private final Logger logger = LoggerFactory.getLogger(PathPipe.class);
 
     public PathPipe(Plumber plumber, Resource resource) throws Exception {
         super(plumber, resource);
+        nodeType = properties.get(PN_NODETYPE, String.class);
         resourceType = properties.get(PN_RESOURCETYPE, NT_SLING_FOLDER);
-        intermediateType = properties.get(PN_INTERMEDIATE, NT_SLING_FOLDER);
+        jcr = StringUtils.isNotBlank(nodeType);
+        intermediateType = properties.get(PN_INTERMEDIATE, resourceType);
         autosave = properties.get(PN_AUTOSAVE, true);
     }
 
@@ -73,11 +82,58 @@ public class PathPipe extends BasePipe {
             String path = expression.startsWith(SLASH) ? expression : getInput().getPath() + SLASH + expression;
             logger.info("creating path {}", path);
             if (!isDryRun()) {
-                output = Collections.singleton(ResourceUtil.getOrCreateResource(resolver, path, resourceType, intermediateType, autosave)).iterator();
+                Resource resource = jcr ? getOrCreateNode(path) : ResourceUtil.getOrCreateResource(resolver, path, resourceType, intermediateType, autosave);
+                output = Collections.singleton(resource).iterator();
             }
         } catch (PersistenceException e){
             logger.error ("Not able to create path {}", expression, e);
         }
         return output;
     }
+
+    /**
+     * get or create JCR path, using pipe members
+     * @param path path to create
+     * @return resource corresponding to the created leaf
+     * @throws RepositoryException in case something went wrong with jcr creation
+     */
+    protected Resource getOrCreateNode(String path) throws RepositoryException {
+        Node leaf = null;
+        boolean transientChange = false;
+        String relativePath = path.substring(1);
+        Node parentNode = resolver.adaptTo(Session.class).getRootNode();
+        if (!parentNode.hasNode(relativePath)) {
+            Node node = parentNode;
+            int pos = relativePath.lastIndexOf('/');
+            if (pos != -1) {
+                final StringTokenizer st = new StringTokenizer(relativePath.substring(0, pos), "/");
+                while (st.hasMoreTokens()) {
+                    final String token = st.nextToken();
+                    if (!node.hasNode(token)) {
+                        try {
+                            node.addNode(token, intermediateType);
+                            transientChange = true;
+                        } catch (RepositoryException re) {
+                            // we ignore this as this folder might be created from a different task
+                            node.getSession().refresh(false);
+                        }
+                    }
+                    node = node.getNode(token);
+                }
+                relativePath = relativePath.substring(pos + 1);
+            }
+            if (!node.hasNode(relativePath)) {
+                node.addNode(relativePath, nodeType);
+                transientChange = true;
+            }
+            leaf = node.getNode(relativePath);
+        }
+        if (leaf == null) {
+            leaf = parentNode.getNode(relativePath);
+        }
+        if (transientChange && autosave) {
+            resolver.adaptTo(Session.class).save();
+        }
+        return resolver.getResource(leaf.getPath());
+    }
 }
diff --git a/src/test/java/org/apache/sling/pipes/internal/PathPipeTest.java b/src/test/java/org/apache/sling/pipes/internal/PathPipeTest.java
index 3ea8db5..f86ad66 100644
--- a/src/test/java/org/apache/sling/pipes/internal/PathPipeTest.java
+++ b/src/test/java/org/apache/sling/pipes/internal/PathPipeTest.java
@@ -17,11 +17,15 @@
 package org.apache.sling.pipes.internal;
 
 import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.pipes.AbstractPipeTest;
 import org.apache.sling.pipes.Pipe;
 import org.junit.Test;
 
+import javax.jcr.Node;
+
+import static org.apache.sling.jcr.resource.JcrResourceConstants.NT_SLING_FOLDER;
 import static org.junit.Assert.*;
 
 /**
@@ -30,7 +34,8 @@ import static org.junit.Assert.*;
 public class PathPipeTest extends AbstractPipeTest {
 
     private static final String WATERMELON = "watermelon";
-    private static final String WATERMELON_FULL_PATH = PATH_FRUITS + "/" + WATERMELON;
+    private static final String WATERMELON_RELATIVEPATH = "parent/" + WATERMELON;
+    private static final String WATERMELON_FULL_PATH = PATH_FRUITS + "/" + WATERMELON_RELATIVEPATH;
 
     @Test
     public void modifiesContent() throws IllegalAccessException, PersistenceException {
@@ -41,17 +46,46 @@ public class PathPipeTest extends AbstractPipeTest {
     }
 
     @Test
-    public void getClassicOutput() throws Exception {
+    public void getClassicOutputResource() throws Exception {
         ResourceResolver resolver = context.resourceResolver();
         plumber.newPipe(resolver).mkdir(WATERMELON_FULL_PATH).run();
-        resolver.revert();
         assertNotNull("Resource should be here & saved", resolver.getResource(WATERMELON_FULL_PATH));
     }
 
     @Test
+    public void getClassicOutputJCR() throws Exception {
+        ResourceResolver resolver = context.resourceResolver();
+        plumber.newPipe(resolver).mkdir(WATERMELON_FULL_PATH).with("nodeType","nt:unstructured","intermediateType",NT_SLING_FOLDER).run();
+        Resource watermelon = resolver.getResource(WATERMELON_FULL_PATH);
+        assertNotNull("Resource should be here & saved", watermelon);
+        Node node = watermelon.adaptTo(Node.class);
+        assertEquals("node type should be nt:unstructured", "nt:unstructured",node.getPrimaryNodeType().getName());
+        assertEquals("Parent node type should be sling:Folder", NT_SLING_FOLDER, node.getParent().getPrimaryNodeType().getName());
+    }
+
+    @Test
+    public void autosaveResourceTest() throws Exception {
+        ResourceResolver resolver = context.resourceResolver();
+        Pipe pipe = plumber.newPipe(resolver).mkdir(WATERMELON_FULL_PATH).with("autosave",false).build();
+        pipe.getOutput().next();
+        resolver.revert();
+        assertNull("Resource should *not* be here", resolver.getResource(WATERMELON_FULL_PATH));
+    }
+
+    @Test
+    public void autosaveJCRTest() throws Exception {
+        ResourceResolver resolver = context.resourceResolver();
+        Pipe pipe = plumber.newPipe(resolver).mkdir(WATERMELON_FULL_PATH).with("nodeType","nt:unstructured","autosave",false).build();
+        pipe.getOutput().next();
+        resolver.revert();
+        Resource watermelon = resolver.getResource(WATERMELON_FULL_PATH);
+        assertNull("JCR Resource should *not* be here", watermelon);
+    }
+
+    @Test
     public void getRelativePath() throws Exception {
         ResourceResolver resolver = context.resourceResolver();
-        plumber.newPipe(resolver).echo(PATH_FRUITS).mkdir(WATERMELON).run();
-        assertNotNull("Resource should be    here & saved", resolver.getResource(WATERMELON_FULL_PATH));
+        plumber.newPipe(resolver).echo(PATH_FRUITS).mkdir(WATERMELON_RELATIVEPATH).run();
+        assertNotNull("Resource should be here & saved", resolver.getResource(WATERMELON_FULL_PATH));
     }
 }
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
npeltier@apache.org.