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 2017/09/20 20:46:36 UTC

svn commit: r1809079 - in /sling/trunk/contrib/extensions/sling-pipes/src: main/java/org/apache/sling/pipes/internal/JsonPipe.java test/java/org/apache/sling/pipes/internal/JsonPipeTest.java

Author: npeltier
Date: Wed Sep 20 20:46:35 2017
New Revision: 1809079

URL: http://svn.apache.org/viewvc?rev=1809079&view=rev
Log:
SLING-7117 add JsonPath configuration

not full json path support even though it could be interesting, as it would need an external library

Modified:
    sling/trunk/contrib/extensions/sling-pipes/src/main/java/org/apache/sling/pipes/internal/JsonPipe.java
    sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/JsonPipeTest.java

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=1809079&r1=1809078&r2=1809079&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 Wed Sep 20 20:46:35 2017
@@ -16,16 +16,6 @@
  */
 package org.apache.sling.pipes.internal;
 
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.Iterator;
-
-import javax.json.JsonArray;
-import javax.json.JsonException;
-import javax.json.JsonStructure;
-import javax.json.JsonValue.ValueType;
-
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.resource.Resource;
@@ -34,12 +24,38 @@ import org.apache.sling.pipes.Plumber;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonStructure;
+import javax.json.JsonValue.ValueType;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * Pipe outputting binding related to a json stream: either an object
  */
 public class JsonPipe extends AbstractInputStreamPipe {
     private static Logger logger = LoggerFactory.getLogger(JsonPipe.class);
-    public static final String RESOURCE_TYPE = RT_PREFIX + "json";
+    public final static String RESOURCE_TYPE = RT_PREFIX + "json";
+
+    /**
+     * property specifying the json path where to fetched the used value
+     */
+    protected static final String PN_VALUEPATH = "valuePath";
+
+    protected static final String JSONPATH_ROOT = "$";
+
+    protected static final String ARRAY_START = "[";
+
+    protected static final String OBJ_START = ".";
+
+    protected static final Pattern JSONPATH_FIRSTTOKEN = Pattern.compile("^\\" + JSONPATH_ROOT + "([\\" + OBJ_START + "\\" + ARRAY_START + "])([^\\" + OBJ_START + "\\]\\" + ARRAY_START + "]+)\\]?");
 
     JsonArray array;
     int index = -1;
@@ -63,35 +79,42 @@ public class JsonPipe extends AbstractIn
                 JsonStructure json;
                 try {
                     json = JsonUtil.parse(jsonString);
+
                 } catch (JsonException ex) {
                     json = null;
                 }
                 if (json == null) {
                     binding = jsonString.trim();
                     output = inputSingletonIterator;
-                } else if (json.getValueType() != ValueType.ARRAY) {
-                    binding = JsonUtil.unbox(json);
-                    output = inputSingletonIterator;
                 } else {
-                    binding = array = (JsonArray) json;
-                    index = 0;
-                    output = new Iterator<Resource>() {
-                        @Override
-                        public boolean hasNext() {
-                            return index < array.size();
-                        }
-
-                        @Override
-                        public Resource next() {
-                            try {
-                                binding = JsonUtil.unbox(array.get(index));
-                            } catch (Exception e) {
-                                logger.error("Unable to retrieve {}nth item of jsonarray", index, e);
+                    String valuePath = properties.get(PN_VALUEPATH, String.class);
+                    if (StringUtils.isNotBlank(valuePath)){
+                        json = getValue(json, valuePath);
+                    }
+                    if (json.getValueType() != ValueType.ARRAY) {
+                        binding = JsonUtil.unbox(json);
+                        output = inputSingletonIterator;
+                    } else {
+                        binding = array = (JsonArray) json;
+                        index = 0;
+                        output = new Iterator<Resource>() {
+                            @Override
+                            public boolean hasNext() {
+                                return index < array.size();
                             }
-                            index++;
-                            return getInput();
-                        }
-                    };
+
+                            @Override
+                            public Resource next() {
+                                try {
+                                    binding = JsonUtil.unbox(array.get(index));
+                                } catch (Exception e) {
+                                    logger.error("Unable to retrieve {}nth item of jsonarray", index, e);
+                                }
+                                index++;
+                                return getInput();
+                            }
+                        };
+                    }
                 }
             }
         }catch (Exception e) {
@@ -99,4 +122,34 @@ public class JsonPipe extends AbstractIn
         }
         return output;
     }
+
+    /**
+     * Returns fetched json value from value path
+     * @param json json structure from which to start
+     * @param valuePath path to follow
+     * @return value fetched after following the path
+     */
+    protected JsonStructure getValue(JsonStructure json, String valuePath){
+        Matcher matcher = JSONPATH_FIRSTTOKEN.matcher(valuePath);
+        if (matcher.find()){
+            String firstChar = matcher.group(1);
+            String content = matcher.group(2);
+            logger.trace("first char is {}, content is {}", firstChar, content);
+            if (ARRAY_START.equals(firstChar)){
+                JsonArray array = (JsonArray)json;
+                int index = Integer.parseInt(content);
+                json = (JsonStructure)array.get(index);
+            } else if (OBJ_START.equals(firstChar)){
+                JsonObject object = (JsonObject)json;
+                json = (JsonStructure)object.get(content);
+            }
+            valuePath = StringUtils.removeStart(valuePath, matcher.group(0));
+            if (StringUtils.isNotBlank(valuePath)){
+                valuePath = JSONPATH_ROOT + valuePath;
+                return getValue(json, valuePath);
+            }
+        }
+        return json;
+    }
+
 }

Modified: sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/JsonPipeTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/JsonPipeTest.java?rev=1809079&r1=1809078&r2=1809079&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/JsonPipeTest.java (original)
+++ sling/trunk/contrib/extensions/sling-pipes/src/test/java/org/apache/sling/pipes/internal/JsonPipeTest.java Wed Sep 20 20:46:35 2017
@@ -22,14 +22,15 @@ import static org.junit.Assert.assertTru
 
 import java.util.Iterator;
 
-import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.pipes.AbstractPipeTest;
-import org.apache.sling.pipes.Pipe;
+import org.apache.sling.pipes.PipeBuilder;
 import org.junit.Before;
 import org.junit.Test;
 
+import javax.json.JsonObject;
+
 /**
  * testing json pipe with anonymous yahoo meteo API
  */
@@ -71,4 +72,23 @@ public class JsonPipeTest extends Abstra
     public void testPipedArray() throws Exception {
         testArray(getOutput(ARRAY));
     }
+
+    @Test
+    public void testSimpleJsonPath() throws Exception {
+        testJsonPath("{'size':2, 'items':[{'test':'one'}, {'test':'two'}]}", "$.items");
+        testJsonPath("[['foo','bar'],[{'test':'one'}, {'test':'two'}]]", "$[1]");
+    }
+    @Test
+    public void testNestedJsonPath()  throws Exception {
+        testJsonPath("{'arrays':[['foo','bar'],[{'test':'one'}, {'test':'two'}]]}", "$.arrays[1]");
+        testJsonPath("{'objects':{'items':[{'test':'one'}, {'test':'two'}]}}", "$.objects.items");
+    }
+
+    protected void testJsonPath(String json, String valuePath) throws Exception {
+        assertEquals("there should be 2 results for valuePath " + valuePath, 2, plumber.newPipe(context.resourceResolver())
+                .echo("/content/fruits")
+                .json(json).with("valuePath", valuePath).name("json")
+                .echo("/content/json/array/${json.test}")
+                .run().size());
+    }
 }
\ No newline at end of file