Author: npeltier
Date: Thu Jul  6 10:04:52 2017
New Revision: 1801010

URL: http://svn.apache.org/viewvc?rev=1801010&view=rev
Log:
SLING-6078 sling pipes fluent API

- allow easy creation & run of pipes from script & java,
- added some tests

Added:
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/PipeBuilder.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java
    
sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/PipeBuilderTest.java
Modified:
    sling/trunk/contrib/extensions/sling-pipes/pom.xml
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/BasePipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/Plumber.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/JsonPipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MovePipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/NotPipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/ParentPipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PlumberImpl.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/SlingQueryPipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/WritePipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java
    
sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/WritePipeTest.java
    sling/trunk/contrib/extensions/sling-pipes/src/test/resources/fruits.json
    sling/trunk/contrib/extensions/sling-pipes/src/test/resources/reference.json

Modified: sling/trunk/contrib/extensions/sling-pipes/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/pom.xml?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/sling-pipes/pom.xml (original)
+++ sling/trunk/contrib/extensions/sling-pipes/pom.xml Thu Jul  6 10:04:52 2017
@@ -150,6 +150,13 @@
       <groupId>org.apache.sling</groupId>
       <artifactId>org.apache.sling.event.api</artifactId>
       <version>1.0.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.jcr.resource</artifactId>
+      <version>2.7.4</version>
+      <scope>compile</scope>
     </dependency>
     <!-- testing -->
     <dependency>
@@ -167,15 +174,15 @@
     <dependency>
       <groupId>org.apache.sling</groupId>
       <artifactId>org.apache.sling.testing.sling-mock</artifactId>
-      <version>2.2.11-SNAPSHOT</version>
+      <version>2.2.12</version>
       <scope>test</scope>
     </dependency>
     <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-json_1.0_spec</artifactId>
-            <version>1.0-alpha-1</version>
-            <scope>provided</scope>
-        </dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-json_1.0_spec</artifactId>
+      <version>1.0-alpha-1</version>
+      <scope>provided</scope>
+    </dependency>
     <dependency>
       <groupId>org.apache.sling</groupId>
       <artifactId>org.apache.sling.commons.johnzon</artifactId>

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/BasePipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/BasePipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/BasePipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/BasePipe.java
 Thu Jul  6 10:04:52 2017
@@ -35,7 +35,8 @@ public class BasePipe implements Pipe {
 
     private final Logger logger = LoggerFactory.getLogger(BasePipe.class);
 
-    public static final String RESOURCE_TYPE = "slingPipes/base";
+    public static final String RT_PREFIX = "slingPipes/";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "base";
     public static final String DRYRUN_KEY = "dryRun";
     public static final String READ_ONLY = "readOnly";
     public static final String PN_STATUS = "status";

Added: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/PipeBuilder.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/PipeBuilder.java?rev=1801010&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/PipeBuilder.java
 (added)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/PipeBuilder.java
 Thu Jul  6 10:04:52 2017
@@ -0,0 +1,158 @@
+/*
+ * 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.sling.pipes;
+
+import org.apache.sling.api.resource.PersistenceException;
+
+import java.util.Set;
+
+/**
+ * Builder & Runner of a pipe, based on a fluent API, for script & java usage.
+ */
+public interface PipeBuilder {
+    /**
+     * attach a new pipe to the current context
+     * @param type
+     * @return
+     */
+    PipeBuilder pipe(String type);
+
+    /**
+     * attach a move pipe to the current context
+     * @param expr
+     * @return
+     */
+    PipeBuilder mv(String expr);
+
+    /**
+     * attach a write pipe to the current context
+     * @param conf configuration parameters
+     * @return
+     */
+    PipeBuilder write(Object... conf) throws IllegalAccessException;
+
+    /**
+     * attach a filter pipe to the current context
+     * @param conf configuration parameters
+     * @return
+     */
+    PipeBuilder filter(Object... conf) throws IllegalAccessException;
+
+    /**
+     * attach an authorizable pipe to the current context
+     * @param conf
+     * @return
+     */
+    PipeBuilder auth(Object... conf) throws IllegalAccessException;
+
+    /**
+     * attach a xpath pipe to the current context
+     * @param expr xpath expression
+     * @return
+     */
+    PipeBuilder xpath(String expr) throws IllegalAccessException;
+
+    /**
+     * attach a sling query pipe to the current context
+     * @param expr sling query expression
+     * @return
+     */
+    PipeBuilder $(String expr) throws IllegalAccessException;
+
+    /**
+     * attach a rm pipe to the current context
+     * @return
+     */
+    PipeBuilder rm();
+
+    /**
+     * attach a json pipe to the current context
+     * @param expr json expr or URL
+     * @return
+     */
+    PipeBuilder json(String expr) throws IllegalAccessException;
+
+    /**
+     * Attach a path pipe to the current context
+     * @param expr
+     * @return
+     */
+    PipeBuilder mkdir(String expr) throws IllegalAccessException;
+
+    /**
+     * attach a base pipe to the current context
+     * @param path pipe path
+     * @return
+     */
+    PipeBuilder echo(String path) throws IllegalAccessException;
+
+    /**
+     * attach a new pipe to the current context
+     * @return
+     */
+    PipeBuilder parent();
+
+    /**
+     * parameterized current pipe in the context
+     * @param param
+     * @param value
+     * @return
+     */
+    PipeBuilder with(String param, String value) throws IllegalAccessException;
+
+    /**
+     * add an expr configuration to the current pipe in the context
+     * @param value
+     * @return
+     */
+    PipeBuilder expr(String value) throws IllegalAccessException;
+
+    /**
+     * sets a pipe name, important in case you want to reuse it in another 
expression
+     * @param name
+     * @return
+     * @throws IllegalAccessException
+     */
+    PipeBuilder name(String name) throws IllegalAccessException;
+
+    /**
+     * add a path configuration to the current pipe in the context
+     * @param value
+     * @return
+     */
+    PipeBuilder path(String value) throws IllegalAccessException;
+
+    /**
+     * Building up a set of configurations for the current pipe
+     * @param properties
+     * @return
+     */
+    PipeBuilder conf(Object... properties) throws IllegalAccessException;
+
+    /**
+     * builds a configured pipe
+     * @return
+     */
+    Pipe build() throws PersistenceException;
+
+    /**
+     * builds & run configured pipe
+     * @return
+     * @throws Exception
+     */
+    Set<String> run() throws Exception;
+}

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/Plumber.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/Plumber.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/Plumber.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/Plumber.java
 Thu Jul  6 10:04:52 2017
@@ -21,6 +21,7 @@ import java.util.Set;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.event.jobs.Job;
 
 /**
@@ -77,6 +78,14 @@ public interface Plumber {
      */
     void registerPipe(String type, Class<? extends BasePipe> pipeClass);
 
+
+    /**
+     * returns wether or not a pipe type is registered
+     * @param type
+     * @return
+     */
+    boolean isTypeRegistered(String type);
+
     /**
      * status of the pipe
      * @param pipeResource resource corresponding to the pipe
@@ -85,6 +94,12 @@ public interface Plumber {
     String getStatus(Resource pipeResource);
 
     /**
+     * Provides a builder helping quickly build & execute a pipe
+     * @return
+     */
+    PipeBuilder getBuilder(ResourceResolver resolver);
+
+    /**
      * returns true if the pipe is considered to be running
      * @param pipeResource resource corresponding to the pipe
      * @return

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java
 Thu Jul  6 10:04:52 2017
@@ -40,7 +40,7 @@ import org.slf4j.LoggerFactory;
  */
 public class AuthorizablePipe extends BasePipe {
     private static Logger logger = 
LoggerFactory.getLogger(AuthorizablePipe.class);
-    public static final String RESOURCE_TYPE = "slingPipes/authorizable";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "authorizable";
     public static final String PN_AUTOCREATEGROUP = "createGroup";
     public static final String PN_ADDTOGROUP = "addToGroup";
     public static final String PN_ADDMEMBERS = "addMembers";

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java
 Thu Jul  6 10:04:52 2017
@@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory;
  */
 public class FilterPipe extends BasePipe {
     private static Logger logger = LoggerFactory.getLogger(FilterPipe.class);
-    public static final String RESOURCE_TYPE = "slingPipes/filter";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "filter";
     public static final String PREFIX_FILTER = "slingPipesFilter_";
     public static final String PN_NOT = PREFIX_FILTER + "not";
     public static final String PN_NOCHILDREN = PREFIX_FILTER + "noChildren";

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/JsonPipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/JsonPipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/JsonPipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/JsonPipe.java
 Thu Jul  6 10:04:52 2017
@@ -45,7 +45,7 @@ import org.slf4j.LoggerFactory;
  */
 public class JsonPipe extends BasePipe {
     private static Logger logger = LoggerFactory.getLogger(JsonPipe.class);
-    public static final String RESOURCE_TYPE = "slingPipes/json";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "json";
 
     HttpClient client;
 

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MovePipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MovePipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MovePipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MovePipe.java
 Thu Jul  6 10:04:52 2017
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
 public class MovePipe extends BasePipe {
     Logger logger = LoggerFactory.getLogger(MovePipe.class);
 
-    public static final String RESOURCE_TYPE = "slingPipes/mv";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "mv";
 
     public MovePipe(Plumber plumber, Resource resource) throws Exception {
         super(plumber, resource);

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java
 Thu Jul  6 10:04:52 2017
@@ -36,7 +36,7 @@ import org.slf4j.LoggerFactory;
  */
 public class MultiPropertyPipe extends BasePipe {
     private static Logger logger = 
LoggerFactory.getLogger(MultiPropertyPipe.class);
-    public static final String RESOURCE_TYPE = "slingPipes/multiProperty";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "multiProperty";
 
     public MultiPropertyPipe(Plumber plumber, Resource resource) throws 
Exception {
         super(plumber, resource);

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/NotPipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/NotPipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/NotPipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/NotPipe.java
 Thu Jul  6 10:04:52 2017
@@ -29,7 +29,7 @@ import org.apache.sling.pipes.ReferenceP
  */
 public class NotPipe extends ReferencePipe {
 
-    public static final String RESOURCE_TYPE = "slingPipes/not";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "not";
 
     public NotPipe(Plumber plumber, Resource resource) throws Exception {
         super(plumber, resource);

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/ParentPipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/ParentPipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/ParentPipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/ParentPipe.java
 Thu Jul  6 10:04:52 2017
@@ -28,7 +28,7 @@ import org.apache.sling.pipes.Plumber;
  */
 public class ParentPipe extends BasePipe {
 
-    public static final String RESOURCE_TYPE = "slingPipes/parent";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "parent";
 
     public ParentPipe(Plumber plumber, Resource resource) throws Exception {
         super(plumber, resource);

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PathPipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
 Thu Jul  6 10:04:52 2017
@@ -25,6 +25,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.pipes.BasePipe;
 import org.apache.sling.pipes.Plumber;
 import org.slf4j.Logger;
@@ -35,7 +36,7 @@ import org.slf4j.LoggerFactory;
  */
 public class PathPipe extends BasePipe {
 
-    public static final String RESOURCE_TYPE = "slingPipes/path";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "path";
     public static final String PN_NODETYPE = "nodeType";
     public static final String PN_AUTOSAVE = "autosave";
 

Added: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java?rev=1801010&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java
 (added)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java
 Thu Jul  6 10:04:52 2017
@@ -0,0 +1,230 @@
+/*
+ * 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.sling.pipes.internal;
+
+import org.apache.commons.lang.StringUtils;
+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.api.resource.ResourceUtil;
+import org.apache.sling.pipes.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+import static 
org.apache.sling.jcr.resource.JcrResourceConstants.NT_SLING_FOLDER;
+import static 
org.apache.sling.jcr.resource.JcrResourceConstants.NT_SLING_ORDERED_FOLDER;
+import static 
org.apache.sling.jcr.resource.JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY;
+
+/**
+ * Implementation of the PipeBuilder interface
+ */
+public class PipeBuilderImpl implements PipeBuilder {
+    private static final Logger logger = 
LoggerFactory.getLogger(PipeBuilderImpl.class);
+
+    public static final String PIPES_REPOSITORY_PATH = "/var/pipes";
+
+    public static final String[] DEFAULT_NAMES = new String[]{"one", "two", 
"three", "four", "five", "six", "seven", "eight", "nine", "ten"};
+
+    List<Step> steps;
+
+    Step currentStep;
+
+    Plumber plumber;
+
+    ResourceResolver resolver;
+
+    /**
+     * protected constructor (to only allow internal classes to build it out)
+     * @param resolver
+     * @param plumber
+     */
+    protected PipeBuilderImpl(ResourceResolver resolver, Plumber plumber){
+        this.plumber = plumber;
+        this.resolver = resolver;
+    }
+
+    @Override
+    public PipeBuilder pipe(String type){
+        if (!plumber.isTypeRegistered(type)){
+            throw new IllegalArgumentException(type + " is not a registered 
pipe type");
+        }
+        if (steps == null){
+            steps = new ArrayList<>();
+        }
+        currentStep = new Step(type);
+        steps.add(currentStep);
+        return this;
+    }
+
+    @Override
+    public PipeBuilder mv(String expr) {
+        return pipe(MovePipe.RESOURCE_TYPE);
+    }
+
+    @Override
+    public PipeBuilder write(Object... conf) throws IllegalAccessException {
+        return pipe(WritePipe.RESOURCE_TYPE).conf(conf);
+    }
+
+    @Override
+    public PipeBuilder filter(Object... conf) throws IllegalAccessException {
+        return pipe(FilterPipe.RESOURCE_TYPE).conf(conf);
+    }
+
+    @Override
+    public PipeBuilder auth(Object... conf) throws IllegalAccessException {
+        return pipe(AuthorizablePipe.RESOURCE_TYPE).conf(conf);
+    }
+
+    @Override
+    public PipeBuilder xpath(String expr) throws IllegalAccessException {
+        return pipe(XPathPipe.RESOURCE_TYPE).expr(expr);
+    }
+
+    @Override
+    public PipeBuilder $(String expr) throws IllegalAccessException {
+        return pipe(SlingQueryPipe.RESOURCE_TYPE).expr(expr);
+    }
+
+    @Override
+    public PipeBuilder rm() {
+        return pipe(RemovePipe.RESOURCE_TYPE);
+    }
+
+    @Override
+    public PipeBuilder json(String expr) throws IllegalAccessException {
+        return pipe(JsonPipe.RESOURCE_TYPE).expr(expr);
+    }
+
+    @Override
+    public PipeBuilder mkdir(String expr) throws IllegalAccessException {
+        return pipe(PathPipe.RESOURCE_TYPE).expr(expr);
+    }
+
+    @Override
+    public PipeBuilder echo(String path) throws IllegalAccessException {
+        return pipe(BasePipe.RESOURCE_TYPE).path(path);
+    }
+
+    @Override
+    public PipeBuilder parent() {
+        return pipe(ParentPipe.RESOURCE_TYPE);
+    }
+
+    /**
+     * check of presence of a current step, fails loudly if it's not the case
+     * @throws IllegalAccessException
+     */
+    protected void checkCurrentStep() throws IllegalAccessException {
+        if (currentStep == null){
+            throw new IllegalAccessException("A pipe should have been 
configured first");
+        }
+    }
+
+    @Override
+    public PipeBuilder with(String param, String value) throws 
IllegalAccessException {
+        checkCurrentStep();
+        currentStep.properties.put(param, value);
+        return this;
+    }
+
+    @Override
+    public PipeBuilder expr(String value) throws IllegalAccessException {
+        return this.with(Pipe.PN_EXPR, value);
+    }
+
+    @Override
+    public PipeBuilder path(String value) throws IllegalAccessException {
+        return this.with(Pipe.PN_PATH, value);
+    }
+
+    @Override
+    public PipeBuilder name(String name) throws IllegalAccessException {
+        checkCurrentStep();
+        currentStep.name = name;
+        return this;
+    }
+
+    @Override
+    public PipeBuilder conf(Object... properties) throws 
IllegalAccessException {
+        checkCurrentStep();
+        if (properties.length % 2 > 0){
+            throw new IllegalArgumentException("there should be an even number 
of arguments");
+        }
+        for (int i = 0; i < properties.length; i += 2){
+            currentStep.conf.put(properties[i], properties[i + 1]);
+        }
+        return this;
+    }
+
+    /**
+     * build a time + random based path under /var/pipes
+     * @return
+     */
+    protected String buildPipePath() {
+        final Calendar now = Calendar.getInstance();
+        return PIPES_REPOSITORY_PATH + '/' + now.get(Calendar.YEAR) + '/' + 
now.get(Calendar.MONTH) + '/' + now.get(Calendar.DAY_OF_MONTH) + "/"
+                + UUID.randomUUID().toString();
+    }
+
+    @Override
+    public Pipe build() throws PersistenceException {
+        String rootPath = buildPipePath();
+        Resource pipeResource = ResourceUtil.getOrCreateResource(resolver, 
rootPath, ContainerPipe.RESOURCE_TYPE, NT_SLING_FOLDER, true);
+        int index = 0;
+        for (Step step : steps){
+            String name = StringUtils.isNotBlank(step.name) ? step.name : 
DEFAULT_NAMES.length > index ? DEFAULT_NAMES[index] : Integer.toString(index);
+            index++;
+            String subPipePath = rootPath + "/" + Pipe.NN_CONF + "/" + name;
+            ResourceUtil.getOrCreateResource(resolver, subPipePath, 
step.properties, NT_SLING_ORDERED_FOLDER, false);
+            logger.debug("built subpipe {}", subPipePath);
+            if (!step.conf.isEmpty()){
+                ResourceUtil.getOrCreateResource(resolver, subPipePath + "/" + 
Pipe.NN_CONF, step.conf, NT_SLING_FOLDER, false);
+                logger.debug("built subpipe {}'s conf node", subPipePath);
+            }
+        }
+        resolver.commit();
+        logger.debug("built pipe under {}", rootPath);
+        return plumber.getPipe(pipeResource);
+    }
+
+    /**
+     * builds & run configured pipe
+     * @return
+     * @throws Exception
+     */
+    public Set<String> run() throws Exception {
+        Pipe pipe = this.build();
+        return plumber.execute(resolver, pipe, null, new NopWriter(), true);
+    }
+
+    /**
+     * holds a subpipe set of informations
+     */
+    public class Step {
+        String name;
+        Map properties;
+        Map conf;
+        Step(String type){
+            properties = new HashMap();
+            conf = new HashMap();
+            properties.put(SLING_RESOURCE_TYPE_PROPERTY, type);
+        }
+    }
+}

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PlumberImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PlumberImpl.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PlumberImpl.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/PlumberImpl.java
 Thu Jul  6 10:04:52 2017
@@ -52,13 +52,7 @@ import org.apache.sling.distribution.Sim
 import org.apache.sling.event.jobs.Job;
 import org.apache.sling.event.jobs.JobManager;
 import org.apache.sling.event.jobs.consumer.JobConsumer;
-import org.apache.sling.pipes.BasePipe;
-import org.apache.sling.pipes.ContainerPipe;
-import org.apache.sling.pipes.OutputWriter;
-import org.apache.sling.pipes.Pipe;
-import org.apache.sling.pipes.PipeBindings;
-import org.apache.sling.pipes.Plumber;
-import org.apache.sling.pipes.ReferencePipe;
+import org.apache.sling.pipes.*;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
@@ -243,6 +237,11 @@ public class PlumberImpl implements Plum
         registry.put(type, pipeClass);
     }
 
+    @Override
+    public boolean isTypeRegistered(String type) {
+        return registry.containsKey(type);
+    }
+
     /**
      * writes the status of the pipe
      * @param pipe
@@ -271,6 +270,12 @@ public class PlumberImpl implements Plum
     }
 
     @Override
+    public PipeBuilder getBuilder(ResourceResolver resolver) {
+        PipeBuilder builder = new PipeBuilderImpl(resolver, this);
+        return builder;
+    }
+
+    @Override
     public boolean isRunning(Resource pipeResource) {
         return !getStatus(pipeResource).equals(STATUS_FINISHED);
     }

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java
 Thu Jul  6 10:04:52 2017
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
  */
 public class RemovePipe extends BasePipe {
     private static Logger logger = LoggerFactory.getLogger(RemovePipe.class);
-    public static final String RESOURCE_TYPE = "slingPipes/rm";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "rm";
 
     /**
      * In case input resource is a node and configuration is set, only 
configured properties,

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/SlingQueryPipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/SlingQueryPipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/SlingQueryPipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/SlingQueryPipe.java
 Thu Jul  6 10:04:52 2017
@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
 public class SlingQueryPipe extends BasePipe {
     private static Logger logger = 
LoggerFactory.getLogger(SlingQueryPipe.class);
 
-    public final static String RESOURCE_TYPE = "slingPipes/slingQuery";
+    public final static String RESOURCE_TYPE = RT_PREFIX + "slingQuery";
 
     public SlingQueryPipe(Plumber plumber, Resource resource) throws Exception 
{
         super(plumber, resource);

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/WritePipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/WritePipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/WritePipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/WritePipe.java
 Thu Jul  6 10:04:52 2017
@@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory;
  */
 public class WritePipe extends BasePipe {
     private static final Logger logger = 
LoggerFactory.getLogger(WritePipe.class);
-    public static final String RESOURCE_TYPE = "slingPipes/write";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "write";
     Node confTree;
     private List<Resource> propertiesToRemove;
     Pattern addPatch = Pattern.compile("\\+\\[(.*)\\]");

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java
 Thu Jul  6 10:04:52 2017
@@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
 public class XPathPipe extends BasePipe {
 
     private static final Logger logger = 
LoggerFactory.getLogger(XPathPipe.class);
-    public static final String RESOURCE_TYPE = "slingPipes/xpath";
+    public static final String RESOURCE_TYPE = RT_PREFIX + "xpath";
 
     public XPathPipe(Plumber plumber, Resource resource) throws Exception {
         super(plumber, resource);

Added: 
sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/PipeBuilderTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/PipeBuilderTest.java?rev=1801010&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/PipeBuilderTest.java
 (added)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/PipeBuilderTest.java
 Thu Jul  6 10:04:52 2017
@@ -0,0 +1,74 @@
+/*
+ * 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.sling.pipes;
+
+import org.apache.sling.api.resource.ValueMap;
+import org.junit.Test;
+
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
+public class PipeBuilderTest extends AbstractPipeTest {
+    @Test
+    public void simpleBuild() throws Exception {
+        PipeBuilder rmBuilder = plumber.getBuilder(context.resourceResolver());
+        Pipe rmPipe = rmBuilder.echo(PATH_APPLE).rm().build();
+        assertNotNull(" a pipe should be built", rmPipe);
+        //we rebuild pipe out of created pipe path, execute it, and test 
correct output (= correct pipe built)
+        testOneResource(rmPipe.getResource().getPath(), PATH_FRUITS);
+    }
+
+    @Test
+    public void run() throws Exception {
+        String lemonPath = "/content/fruits/lemon";
+        PipeBuilder lemonBuilder = 
plumber.getBuilder(context.resourceResolver());
+        Set<String> paths = lemonBuilder.mkdir(lemonPath).run();
+        assertTrue("returned set should contain lemon path", 
paths.contains(lemonPath));
+        assertNotNull("there should be a lemon created", 
context.resourceResolver().getResource(lemonPath));
+    }
+
+    @Test
+    public void confBuild() throws Exception {
+        PipeBuilder writeBuilder = 
plumber.getBuilder(context.resourceResolver());
+        writeBuilder.echo(PATH_APPLE).write("tested", true, "working", 
true).run();
+        ValueMap properties = 
context.resourceResolver().getResource(PATH_APPLE).adaptTo(ValueMap.class);
+        assertTrue("properties should have been written", 
properties.get("tested", false) && properties.get("working", false));
+    }
+
+    @Test
+    public void bindings() throws Exception {
+        PipeBuilder defaultNames = 
plumber.getBuilder(context.resourceResolver());
+        Set<String> paths = defaultNames
+                .echo(PATH_FRUITS)
+                .$("nt:unstructured")
+                .filter("slingPipesFilter_test","${two.worm}")
+                .$("nt:unstructured#isnota")
+                .$("nt:unstructured").name("thing")
+                .write("jcr:path", "${path.thing}").run();
+        assertEquals("There should be only one resource", 2, paths.size());
+        String pea = "/content/fruits/apple/isnota/pea";
+        String carrot = "/content/fruits/apple/isnota/carrot";
+        assertTrue("the paths should contain " + pea, paths.contains(pea));
+        assertTrue("the paths should contain " + carrot, 
paths.contains(carrot));
+        for (String path : paths){
+            String writtenPath = 
context.resourceResolver().getResource(path).adaptTo(ValueMap.class).get("jcr:path",
 String.class);
+            assertEquals("written path should be the same as actual path", 
path, writtenPath);
+        }
+    }
+
+}
\ No newline at end of file

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/WritePipeTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/WritePipeTest.java?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/WritePipeTest.java
 (original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/WritePipeTest.java
 Thu Jul  6 10:04:52 2017
@@ -57,7 +57,7 @@ public class WritePipeTest extends Abstr
         assertTrue("this pipe should be marked as content modifier", 
pipe.modifiesContent());
         pipe.getOutput();
         context.resourceResolver().commit();
-        ValueMap properties =  
context.resourceResolver().getResource("/content/fruits/apple").adaptTo(ValueMap.class);
+        ValueMap properties =  
context.resourceResolver().getResource(PATH_APPLE).adaptTo(ValueMap.class);
         assertTrue("There should be hasSeed set to true", 
properties.get("hasSeed", false));
         assertArrayEquals("Colors should be correctly set", new 
String[]{"green", "red"}, properties.get("colors", String[].class));
         assertFalse("worm property should be gone (${null} conf)", 
properties.get("worm", false));
@@ -116,7 +116,7 @@ public class WritePipeTest extends Abstr
         assertTrue("this pipe should be marked as content modifier", 
pipe.modifiesContent());
         pipe.getOutput();
         context.resourceResolver().commit();
-        Resource appleResource = 
context.resourceResolver().getResource("/content/fruits/apple");
+        Resource appleResource = 
context.resourceResolver().getResource(PATH_APPLE);
         ValueMap properties =  appleResource.adaptTo(ValueMap.class);
         assertTrue("There should be hasSeed set to true", 
properties.get("hasSeed", false));
         assertArrayEquals("Colors should be correctly set", new 
String[]{"green", "red"}, properties.get("colors", String[].class));

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/test/resources/fruits.json
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/test/resources/fruits.json?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/sling-pipes/src/test/resources/fruits.json 
(original)
+++ sling/trunk/contrib/extensions/sling-pipes/src/test/resources/fruits.json 
Thu Jul  6 10:04:52 2017
@@ -3,7 +3,7 @@
   "index":["apple","banana"],
   "apple":{
     "jcr:primaryType":"nt:unstructured",
-    "worm":"true",
+    "worm": true,
     "isnota":{
       "jcr:primaryType":"nt:unstructured",
       "pea":{

Modified: 
sling/trunk/contrib/extensions/sling-pipes/src/test/resources/reference.json
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/test/resources/reference.json?rev=1801010&r1=1801009&r2=1801010&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/sling-pipes/src/test/resources/reference.json 
(original)
+++ 
sling/trunk/contrib/extensions/sling-pipes/src/test/resources/reference.json 
Thu Jul  6 10:04:52 2017
@@ -20,7 +20,7 @@
     "sling:resourceType": "slingPipes/filter",
     "conf":{
       "jcr:primaryType": "nt:unstructured",
-      "slingPipesFilter_test":"${fruit.worm === 'true'}"
+      "slingPipesFilter_test":"${fruit.worm}"
     }
   },
   "simple": {


Reply via email to