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