You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2014/06/13 11:02:38 UTC
[09/20] git commit: Add fn:jsonpath to evaluate a JSONPath expression
on a value
Add fn:jsonpath to evaluate a JSONPath expression on a value
JSONPath: https://github.com/jayway/JsonPath
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/ac782081
Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/ac782081
Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/ac782081
Branch: refs/heads/ldp
Commit: ac782081f8c5733b91a76d0d79895f07678e2b8d
Parents: fa98d10
Author: Chris Beer <ca...@stanford.edu>
Authored: Wed Jun 4 13:46:32 2014 -0700
Committer: Chris Beer <ca...@stanford.edu>
Committed: Thu Jun 5 07:35:43 2014 -0700
----------------------------------------------------------------------
libraries/ldpath/ldpath-core-bundle/pom.xml | 10 +-
libraries/ldpath/ldpath-functions-json/pom.xml | 107 +++++++++++++++++++
.../model/functions/json/JsonPathFunction.java | 84 +++++++++++++++
...rmotta.ldpath.api.functions.SelectorFunction | 1 +
.../functions/json/JsonPathFunctionTest.java | 61 +++++++++++
.../src/test/resources/logback.xml | 27 +++++
.../ldpath/model/functions/json/data.n3 | 31 ++++++
libraries/ldpath/ldpath-ldquery-cli/pom.xml | 4 +
.../ldpath/ldpath-template-linkeddata/pom.xml | 4 +
libraries/ldpath/pom.xml | 1 +
parent/pom.xml | 10 ++
11 files changed, 339 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-core-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-core-bundle/pom.xml b/libraries/ldpath/ldpath-core-bundle/pom.xml
index fdf351f..893f1cd 100644
--- a/libraries/ldpath/ldpath-core-bundle/pom.xml
+++ b/libraries/ldpath/ldpath-core-bundle/pom.xml
@@ -75,6 +75,11 @@
<artifactId>ldpath-functions-xml</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>ldpath-functions-json</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
@@ -94,6 +99,7 @@
NOTES:
* jdom2 is required for using the ldpath-functions-xml
* jsoup is required for using the ldpath-functions-html
+ * jsonpath is required for using the ldpath-functions-json
-->
<Import-Package>
org.slf4j.*;version="[1.6,2)",
@@ -101,6 +107,7 @@
ch.qos.logback.classic;resolution:=optional,
org.jdom2.*;resolution:=optional,
org.jsoup.*;resolution:=optional,
+ com.jayway.jsonpath.*;resolution:=optional,
*
</Import-Package>
<_exportcontents>
@@ -114,7 +121,8 @@
ldpath-core,
ldpath-functions-collections, ldpath-functions-date,
ldpath-functions-html, ldpath-functions-math,
- ldpath-functions-text, ldpath-functions-xml
+ ldpath-functions-text, ldpath-functions-xml,
+ ldpath-functions-json
</Embed-Dependency>
</instructions>
</configuration>
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-functions-json/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-json/pom.xml b/libraries/ldpath/ldpath-functions-json/pom.xml
new file mode 100644
index 0000000..3c6ae66
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-json/pom.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>marmotta-parent</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ <relativePath>../../../parent</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>LDPath Functions: JSON</name>
+ <artifactId>ldpath-functions-json</artifactId>
+ <packaging>jar</packaging>
+
+ <description>LDPath Functions for JSON content.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>ldpath-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>ldpath-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.jayway.jsonpath</groupId>
+ <artifactId>json-path</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>ldpath-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>ldpath-backend-sesame</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openrdf.sesame</groupId>
+ <artifactId>sesame-repository-sail</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openrdf.sesame</groupId>
+ <artifactId>sesame-sail-memory</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openrdf.sesame</groupId>
+ <artifactId>sesame-rio-n3</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin> <!-- generate JRebel Configuration -->
+ <groupId>org.zeroturnaround</groupId>
+ <artifactId>jrebel-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-rebel-xml</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <relativePath>../../../</relativePath>
+ <rootPath>$${rebel.root}</rootPath>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <!-- No License-Header in META-INF/services -->
+ <exclude>src/main/resources/META-INF/services/*</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-functions-json/src/main/java/org/apache/marmotta/ldpath/model/functions/json/JsonPathFunction.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-json/src/main/java/org/apache/marmotta/ldpath/model/functions/json/JsonPathFunction.java b/libraries/ldpath/ldpath-functions-json/src/main/java/org/apache/marmotta/ldpath/model/functions/json/JsonPathFunction.java
new file mode 100644
index 0000000..4e80ec8
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-json/src/main/java/org/apache/marmotta/ldpath/model/functions/json/JsonPathFunction.java
@@ -0,0 +1,84 @@
+package org.apache.marmotta.ldpath.model.functions.json;
+
+import com.jayway.jsonpath.JsonPath;
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
+import org.apache.marmotta.ldpath.model.transformers.StringTransformer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public class JsonPathFunction<Node> extends SelectorFunction<Node> {
+
+ private static final Logger log = LoggerFactory.getLogger(JsonPathFunction.class);
+ private final StringTransformer<Node> transformer = new StringTransformer<Node>();
+
+ @Override
+ protected String getLocalName() {
+ return "jsonpath";
+ }
+
+ @Override
+ public Collection<Node> apply(RDFBackend<Node> rdfBackend, Node context, @SuppressWarnings("unchecked") Collection<Node>... args) throws IllegalArgumentException {
+
+ Set<String> jsonpaths = new HashSet<String>();
+ for (Node jsonpath : args[0]) {
+ try {
+ jsonpaths.add(transformer.transform(rdfBackend,jsonpath, null));
+ } catch (IllegalArgumentException iae) {
+ throw new IllegalArgumentException("First argument must not contain anything else than String-Literals!");
+ }
+ }
+
+ Iterator<Node> it;
+ if(args.length < 2){
+ log.debug("Use context {} to execute jsonpaths {}",context,jsonpaths);
+ it = Collections.singleton(context).iterator();
+ } else {
+ log.debug("execute jsonpaths {} on parsed parameters",jsonpaths);
+ it = org.apache.marmotta.ldpath.util.Collections.iterator(1,args);
+ }
+
+ List<Node> result = new ArrayList<Node>();
+ while (it.hasNext()) {
+ Node n = it.next();
+ try {
+ for (String r : doFilter(transformer.transform(rdfBackend,n, null), jsonpaths)) {
+ result.add(rdfBackend.createLiteral(r));
+ }
+ } catch (IOException e) {
+ // This should never happen, since validation is turned off.
+ }
+ }
+
+ return result;
+ }
+
+ private List<String> doFilter(String in, Set<String> jsonpaths) throws IOException {
+ List<String> result = new ArrayList<String>();
+
+ for (String jsonpath : jsonpaths) {
+ result.add(String.valueOf(JsonPath.read(in, jsonpath)));
+ }
+
+ return result;
+ }
+
+ @Override
+ public String getSignature() {
+ return "fn:json(json: String [, nodes: JsonPathList]) : LiteralList";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Evaluate a JSONPath expression on either the value of the context node or the values of the nodes passed as arguments.";
+ }
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-functions-json/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-json/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction b/libraries/ldpath/ldpath-functions-json/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
new file mode 100644
index 0000000..64c8f37
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-json/src/main/resources/META-INF/services/org.apache.marmotta.ldpath.api.functions.SelectorFunction
@@ -0,0 +1 @@
+org.apache.marmotta.ldpath.model.functions.json.JsonPathFunction
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-functions-json/src/test/java/org/apache/marmotta/ldpath/model/functions/json/JsonPathFunctionTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-json/src/test/java/org/apache/marmotta/ldpath/model/functions/json/JsonPathFunctionTest.java b/libraries/ldpath/ldpath-functions-json/src/test/java/org/apache/marmotta/ldpath/model/functions/json/JsonPathFunctionTest.java
new file mode 100644
index 0000000..923e944
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-json/src/test/java/org/apache/marmotta/ldpath/model/functions/json/JsonPathFunctionTest.java
@@ -0,0 +1,61 @@
+package org.apache.marmotta.ldpath.model.functions.json;
+
+import com.google.common.collect.Lists;
+import org.apache.marmotta.ldpath.model.fields.FieldMapping;
+import org.apache.marmotta.ldpath.parser.LdPathParser;
+import org.apache.marmotta.ldpath.parser.ParseException;
+import org.apache.marmotta.ldpath.test.AbstractTestBase;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFParseException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+
+@RunWith(Parameterized.class)
+public class JsonPathFunctionTest extends AbstractTestBase {
+
+ @Parameterized.Parameters(name = "{1}")
+ public static List<String[]> data() {
+ ArrayList<String[]> data = new ArrayList<String[]>();
+ data.add(new String[] { "$.string", "stringValue" });
+ data.add(new String[] { "$.int", "0" });
+ data.add(new String[] { "$..child[0]", "a" });
+ data.add(new String[] { "$.array", "[{\"child\":\"a\"},{\"child\":\"b\"}]" });
+ data.add(new String[] { "$..child", "[\"a\",\"b\"]" });
+ return data;
+ }
+
+ @Parameterized.Parameter
+ public String path;
+ @Parameterized.Parameter(1)
+ public String answer;
+
+ @Before
+ public void loadData() throws RepositoryException, RDFParseException, IOException {
+ super.loadData("data.n3", RDFFormat.N3);
+ }
+
+ @Test
+ public void testJsonPathFunction() throws ParseException {
+
+ final URI ctx = repository.getValueFactory().createURI(NSS.get("ex") + "Quiz");
+
+ final LdPathParser<Value> parser = createParserFromString("fn:jsonpath(\"" + path + "\", <http://www.w3.org/2011/content#chars>) :: xsd:string");
+ final FieldMapping<Object, Value> rule = parser.parseRule(NSS);
+ final Collection<Object> values = rule.getValues(backend, ctx);
+
+ Assert.assertEquals(1, values.size());
+ Assert.assertEquals(answer, values.iterator().next());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-functions-json/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-json/src/test/resources/logback.xml b/libraries/ldpath/ldpath-functions-json/src/test/resources/logback.xml
new file mode 100644
index 0000000..1bfecff
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-json/src/test/resources/logback.xml
@@ -0,0 +1,27 @@
+<!--
+ ~ 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.
+ -->
+
+<configuration>
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} %highlight(%level) %cyan(%logger{15}) - %m%n</pattern>
+ </encoder>
+ </appender>
+ <root level="${root-level:-INFO}">
+ <appender-ref ref="CONSOLE"/>
+ </root>
+</configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-functions-json/src/test/resources/org/apache/marmotta/ldpath/model/functions/json/data.n3
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-functions-json/src/test/resources/org/apache/marmotta/ldpath/model/functions/json/data.n3 b/libraries/ldpath/ldpath-functions-json/src/test/resources/org/apache/marmotta/ldpath/model/functions/json/data.n3
new file mode 100644
index 0000000..bfeec91
--- /dev/null
+++ b/libraries/ldpath/ldpath-functions-json/src/test/resources/org/apache/marmotta/ldpath/model/functions/json/data.n3
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+@prefix ex: <http://www.example.com/> .
+@prefix cnt: <http://www.w3.org/2011/content#> .
+
+ex:Quiz a ex:Test, cnt:ContentAsText;
+ cnt:chars """
+ {
+ "string": "stringValue",
+ "int": 0,
+ "array": [
+ { "child": "a" },
+ { "child": "b" }
+ ]
+ }
+ """ .
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-ldquery-cli/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-ldquery-cli/pom.xml b/libraries/ldpath/ldpath-ldquery-cli/pom.xml
index a81d56a..63358d7 100644
--- a/libraries/ldpath/ldpath-ldquery-cli/pom.xml
+++ b/libraries/ldpath/ldpath-ldquery-cli/pom.xml
@@ -176,6 +176,10 @@
<artifactId>ldpath-functions-xml</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>ldpath-functions-json</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.marmotta</groupId>
<artifactId>ldpath-functions-math</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/ldpath-template-linkeddata/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldpath/ldpath-template-linkeddata/pom.xml b/libraries/ldpath/ldpath-template-linkeddata/pom.xml
index bef5b39..1e8845f 100644
--- a/libraries/ldpath/ldpath-template-linkeddata/pom.xml
+++ b/libraries/ldpath/ldpath-template-linkeddata/pom.xml
@@ -118,6 +118,10 @@
</dependency>
<dependency>
<groupId>org.apache.marmotta</groupId>
+ <artifactId>ldpath-functions-json</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.marmotta</groupId>
<artifactId>ldpath-functions-math</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/libraries/ldpath/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldpath/pom.xml b/libraries/ldpath/pom.xml
index cb6a5c1..0e6b4a6 100644
--- a/libraries/ldpath/pom.xml
+++ b/libraries/ldpath/pom.xml
@@ -100,6 +100,7 @@
<module>ldpath-functions-text</module>
<module>ldpath-functions-math</module>
<module>ldpath-functions-date</module>
+ <module>ldpath-functions-json</module>
<!--
<module>ldpath-backend-sparql</module>
-->
http://git-wip-us.apache.org/repos/asf/marmotta/blob/ac782081/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 2096480..b5196eb 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1639,6 +1639,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>ldpath-functions-json</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.marmotta</groupId>
<artifactId>ldpath-functions-math</artifactId>
<version>${project.version}</version>
@@ -1663,6 +1668,11 @@
<artifactId>jsoup</artifactId>
<version>1.7.2</version>
</dependency>
+ <dependency>
+ <groupId>com.jayway.jsonpath</groupId>
+ <artifactId>json-path</artifactId>
+ <version>0.9.1</version>
+ </dependency>
<dependency>
<groupId>junit</groupId>