This is an automated email from the ASF dual-hosted git repository. Cole-Greer pushed a commit to branch SPARQL-Gremlin-Removal in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 8fbe40a05bf1caa90c4c820f457c21b64eb74551 Author: Cole Greer <[email protected]> AuthorDate: Thu May 14 17:08:03 2026 -0700 TINKERPOP-3249: Remove sparql-gremlin --- .github/workflows/build-test.yml | 2 +- docs/preprocessor/install-plugins.sh | 2 +- docs/site/home/community.html | 4 - docs/src/reference/compilers.asciidoc | 440 --------------------- docs/src/reference/index.asciidoc | 1 - docs/src/reference/intro.asciidoc | 3 +- docs/src/upgrade/release-4.x.x.asciidoc | 7 + .../structure/io/graphson/GraphSONModule.java | 17 +- .../gremlin/structure/io/gryo/GryoVersion.java | 3 +- pom.xml | 1 - sparql-gremlin/pom.xml | 69 ---- .../apache/tinkerpop/gremlin/sparql/Prefixes.java | 65 --- .../gremlin/sparql/SparqlToGremlinCompiler.java | 318 --------------- .../tinkerpop/gremlin/sparql/TraversalBuilder.java | 83 ---- .../gremlin/sparql/WhereTraversalBuilder.java | 128 ------ .../gremlin/sparql/jsr223/SparqlGremlinPlugin.java | 63 --- .../dsl/sparql/DefaultSparqlTraversal.java | 55 --- .../traversal/dsl/sparql/SparqlTraversal.java | 62 --- .../dsl/sparql/SparqlTraversalSource.java | 182 --------- .../process/traversal/strategy/SparqlStrategy.java | 88 ----- ...g.apache.tinkerpop.gremlin.jsr223.GremlinPlugin | 1 - .../tinkerpop/gremlin/sparql/PrefixesTest.java | 67 ---- .../dsl/sparql/SparqlTraversalSourceTest.java | 189 --------- .../src/test/resources/logback-silent.xml | 26 -- sparql-gremlin/src/test/resources/logback-test.xml | 26 -- 25 files changed, 12 insertions(+), 1890 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 9567897ea3..72f80cd461 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -5,7 +5,7 @@ env: # take care when modifying this list because GLVs use shell commands to remove themselves from this list and # modifications could break patterns of replacement they are searching for. EXCLUDE_MODULES: '-:gremlin-dotnet-source,-:gremlin-dotnet-tests,-:gremlin-go,-:gremlin-js,-:gremlin-javascript,-:gremlint,-:gremlin-mcp,-:gremlin-python' - EXCLUDE_FOR_GLV: '-:gremlin-console,-:gremlin-coverage,-:hadoop-gremlin,-:spark-gremlin,-:sparql-gremlin' + EXCLUDE_FOR_GLV: '-:gremlin-console,-:gremlin-coverage,-:hadoop-gremlin,-:spark-gremlin' jobs: smoke: name: smoke diff --git a/docs/preprocessor/install-plugins.sh b/docs/preprocessor/install-plugins.sh index 7a03d1d5d9..7b99010707 100755 --- a/docs/preprocessor/install-plugins.sh +++ b/docs/preprocessor/install-plugins.sh @@ -25,7 +25,7 @@ TMP_DIR=$3 INSTALL_TEMPLATE="docs/preprocessor/install-plugins.groovy" INSTALL_FILE="${TMP_DIR}/install-plugins.groovy" -plugins=("hadoop-gremlin" "spark-gremlin" "sparql-gremlin") +plugins=("hadoop-gremlin" "spark-gremlin") # plugins=() pluginsCount=${#plugins[@]} diff --git a/docs/site/home/community.html b/docs/site/home/community.html index 38db69b595..b5725e9a52 100644 --- a/docs/site/home/community.html +++ b/docs/site/home/community.html @@ -1174,10 +1174,6 @@ l = g.V().both()[1:3].toList()</code></pre> href="https://github.com/opencypher/cypher-for-gremlin" target="_blank">cypher-for-gremlin</a>: A Cypher-to-Gremlin traversal transpiler. - <br>- <a class="text-blue" - href="https://tinkerpop.apache.org/docs/current/reference/#sparql-gremlin" - target="_blank">sparql-gremlin</a>: A SPARQL to Gremlin traversal - compiler. <br>- <a class="text-blue" href="https://github.com/twilmes/sql-gremlin" target="_blank">sql-gremlin</a>: A SQL to Gremlin traversal compiler. </p> diff --git a/docs/src/reference/compilers.asciidoc b/docs/src/reference/compilers.asciidoc deleted file mode 100644 index 51f8c4c909..0000000000 --- a/docs/src/reference/compilers.asciidoc +++ /dev/null @@ -1,440 +0,0 @@ -//// -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. -//// -[[compilers]] -= Gremlin Compilers - -There are many languages built to query data. SQL is typically used to query relational data. There is SPARQL for RDF -data. Cypher is used to do pattern matching in graph data. The list could go on. Compilers convert languages like -these to Gremlin so that it becomes possible to use them in any context that Gremlin is used. In other words, a -Gremlin Compiler enables a particular query language to work on any TinkerPop-enabled graph system. - -[[sparql-gremlin]] -== SPARQL-Gremlin - -WARNING: The sparql-gremlin module is not included in the 4.0.0-beta.2 distribution. The examples in this -section are presented as static code and will be restored in a future release. - -image::gremlintron.png[width=225] - -The SPARQL-Gremlin compiler, transforms link:https://en.wikipedia.org/wiki/SPARQL[SPARQL] queries into Gremlin -traversals. It uses the https://jena.apache.org/index.html[Apache Jena] SPARQL processor -link:https://jena.apache.org/documentation/query/index.html[ARQ], which provides access to a syntax tree of a -SPARQL query. - -The goal of this work is to bridge the query interoperability gap between the two famous, yet fairly disconnected, -graph communities: Semantic Web (which relies on the RDF data model) and Graph database (which relies on property graph -data model). - -NOTE: The foundational research work on SPARQL-Gremlin compiler (aka Gremlinator) can be found in the -link:https://arxiv.org/pdf/1801.02911.pdf[Gremlinator paper]. This paper presents the graph query language semantics of -SPARQL and Gremlin, and a formal mapping between SPARQL pattern matching graph patterns and Gremlin traversals. - -[source,xml] ----- -<dependency> - <groupId>org.apache.tinkerpop</groupId> - <artifactId>sparql-gremlin</artifactId> - <version>x.y.z</version> -</dependency> ----- - -The SPARQL-Gremlin compiler converts link:https://en.wikipedia.org/wiki/SPARQL[SPARQL] queries into Gremlin so that -they can be executed across any TinkerPop-enabled graph system. To use this compiler in the Gremlin Console, first -install and activate the "tinkerpop.sparql" plugin: - -[source,text] ----- -gremlin> :install org.apache.tinkerpop sparql-gremlin x.y.z -==>Loaded: [org.apache.tinkerpop, sparql-gremlin, x.y.z] -gremlin> :plugin use tinkerpop.sparql -==>tinkerpop.sparql activated ----- - -Installing this plugin will download appropriate dependencies and import certain classes to the console so that they -may be used as follows: - -[source,groovy] ----- -graph = TinkerFactory.createModern() -g = traversal(SparqlTraversalSource).with(graph) <1> -g.sparql("""SELECT ?name ?age - WHERE { ?person v:name ?name . ?person v:age ?age } - ORDER BY ASC(?age)""") <2> ----- - -<1> Define `g` as a `TraversalSource` that uses the `SparqlTraversalSource` - by default, the `traversal()` method -usually returns a `GraphTraversalSource` which includes the standard Gremlin starts steps like `V()` or `E()`. In this -case, the `SparqlTraversalSource` enables starts steps that are specific to SPARQL only - in this case the `sparql()` -start step. -<2> Execute a SPARQL query against the TinkerGraph instance. The `SparqlTraversalSource` uses a -<<traversalstrategy,TraversalStrategy>> to transparently converts that SPARQL query into a standard Gremlin traversal -and then when finally iterated, executes that against the TinkerGraph. - -[[prefixes]] -=== Prefixes - -The SPARQL-Gremlin compiler supports the following prefixes to traverse the graph: - -[cols=",",options="header",] -|==================================== -|Prefix |Purpose -|`v:<id\|label\|<name>>` |access to vertex id, label or property value -|`e:<label>` |out-edge traversal -|`p:<name>` |property traversal -|==================================== - -Note that element IDs and labels are treated like normal properties, hence they can be accessed using the same pattern: - -[source,groovy] ----- -g.sparql("""SELECT ?name ?id ?label - WHERE { - ?element v:name ?name . - ?element v:id ?id . - ?element v:label ?label .}""") ----- - -[[supported-queries]] -=== Supported Queries - -The SPARQL-Gremlin compiler currently supports translation of the SPARQL 1.0 specification, especially `SELECT` -queries, though there is an on-going effort to cover the entire SPARQL 1.1 query feature spectrum. The supported -SPARQL query types are: - -* Union -* Optional -* Order-By -* Group-By -* STAR-shaped or _neighbourhood queries_ -* Query modifiers, such as: -** Filter with _restrictions_ -** Count -** LIMIT -** OFFSET - -[[limitations]] -=== Limitations - -The current implementation of SPARQL-Gremlin compiler (i.e. SPARQL-Gremlin) does not support the following cases: - -* SPARQL queries with variables in the predicate position are not currently covered, with an exception of the following -case: - -[source,groovy] ----- -g.sparql("""SELECT * WHERE { ?x ?y ?z . }""") ----- - -* A SPARQL Union query with un-balanced patterns, i.e. a gremlin union traversal can only be generated if the input -SPARQL query has the same number of patterns on both the side of the union operator. For instance, the following -SPARQL query cannot be mapped, since a union is executed between different number of graph patterns (two patterns -`union` 1 pattern). - -[source,groovy] ----- -g.sparql("""SELECT * - WHERE { - {?person e:created ?software . - ?person v:name "josh" .} - UNION - {?software v:lang "java" .} }""") ----- - -* A non-Group key variable cannot be projected in a SPARQL query. This is a SPARQL language limitation rather than -that of Gremlin/TinkerPop. Apache Jena throws the exception "Non-group key variable in SELECT" if this occurs. -For instance, in a SPARQL query with GROUP-BY clause, only the variable on which the grouping is declared, can be -projected. The following query is valid: - -[source,groovy] ----- -g.sparql("""SELECT ?age - WHERE { - ?person v:label "person" . - ?person v:age ?age . - ?person v:name ?name .} GROUP BY (?age)""") ----- - -Whereas, the following SPARQL query will be invalid: - -[source,groovy] ----- -g.sparql("""SELECT ?person - WHERE { - ?person v:label "person" . - ?person v:age ?age . - ?person v:name ?name .} GROUP BY (?age)""") ----- - -* In a SPARQL query with an ORDER-BY clause, the ordering occurs with respect to the first projected variable in the -query. It is possible to choose any number of variable to be projected, however, the first variable in the selection -will be the ordering decider. For instance, in the query: - -[source,groovy] ----- -g.sparql("""SELECT ?name ?age - WHERE { - ?person v:label "person" . - ?person v:age ?age . - ?person v:name ?name . } ORDER BY (?age)""") ----- - -the result set will be ordered according to the `?name` variable (in ascending order by default) despite having passed -`?age` in the order by. Whereas, for the following query: - -[source,groovy] ----- -g.sparql("""SELECT ?age ?name - WHERE { - ?person v:label "person" . - ?person v:age ?age . - ?person v:name ?name . } ORDER BY (?age)""") ----- - -the result set will be ordered according to the `?age` (as it is the first projected variable). Finally, for the -select all case (`SELECT *`): - -[source,groovy] ----- -g.sparql("""SELECT * - WHERE { ?person v:label "person" . ?person v:age ?age . ?person v:name ?name . } ORDER BY (?age)""") ----- - -the the variable encountered first will be the ordering decider, i.e. since we have `?person` encountered first, -the result set will be ordered according to the `?person` variable (which are vertex id). - -* In the current implementation, `OPTIONAL` clause doesn't work under nesting with `UNION` clause (i.e. multiple optional -clauses with in a union clause) and `ORDER-By` clause (i.e. declaring ordering over triple patterns within optional -clauses). Everything else with SPARQL `OPTIONAL` works just fine. - -[[examples]] -=== Examples - -The following section presents examples of SPARQL queries that are currently covered by the SPARQL-Gremlin compiler. - -==== Select All - -Select all vertices in the graph. - -[source,groovy] ----- -g.sparql("""SELECT * WHERE { }""") ----- - -==== Match Constant Values - -Select all vertices with the label `person`. - -[source,groovy] ----- -g.sparql("""SELECT * WHERE { ?person v:label "person" .}""") ----- - -==== Select Specific Elements - -Select the values of the properties `name` and `age` for each `person` vertex. - -[source,groovy] ----- -g.sparql("""SELECT ?name ?age -WHERE { - ?person v:label "person" . - ?person v:name ?name . - ?person v:age ?age . }""") ----- - -==== Pattern Matching - -Select only those persons who created a project. - -[source,groovy] ----- -g.sparql("""SELECT ?name ?age -WHERE { - ?person v:label "person" . - ?person v:name ?name . - ?person v:age ?age . - ?person e:created ?project . }""") ----- - -==== Filtering - -Select only those persons who are older than 30. - -[source,groovy] ----- -g.sparql("""SELECT ?name ?age -WHERE { - ?person v:label "person" . - ?person v:name ?name . - ?person v:age ?age . - FILTER (?age > 30) }""") ----- - -==== Deduplication - -Select the distinct names of the created projects. - -[source,groovy] ----- -g.sparql("""SELECT DISTINCT ?name -WHERE { - ?person v:label "person" . - ?person v:age ?age . - ?person e:created ?project . - ?project v:name ?name . - FILTER (?age > 30)}""") ----- - -==== Multiple Filters - -Select the distinct names of all Java projects. - -[source,groovy] ----- -g.sparql("""SELECT DISTINCT ?name -WHERE { - ?person v:label "person" . - ?person v:age ?age . - ?person e:created ?project . - ?project v:name ?name . - ?project v:lang ?lang . - FILTER (?age > 30 && ?lang = "java") }""") ----- - -==== Union - -Select all persons who have developed a software in java using union. - -[source,groovy] ----- -g.sparql("""SELECT * -WHERE { - {?person e:created ?software .} - UNION - {?software v:lang "java" .} }""") ----- - -==== Optional - -Return the names of the persons who have created a software in java and optionally python. - -[source,groovy] ----- -g.sparql("""SELECT ?person -WHERE { - ?person v:label "person" . - ?person e:created ?software . - ?software v:lang "java" . - OPTIONAL {?software v:lang "python" . }}""") ----- - -==== Order By - -Select all vertices with the label `person` and order them by their age. - -[source,groovy] ----- -g.sparql("""SELECT ?age ?name -WHERE { - ?person v:label "person" . - ?person v:age ?age . - ?person v:name ?name . -} ORDER BY (?age)""") ----- - -==== Group By - -Select all vertices with the label `person` and group them by their age. - -[source,groovy] ----- -g.sparql("""SELECT ?age -WHERE { - ?person v:label "person" . - ?person v:age ?age . -} GROUP BY (?age)""") ----- - -==== Mixed/complex/aggregation-based queries - -Count the number of projects which have been created by persons under the age of 30 and group them by age. Return only -the top two. - -[source,groovy] ----- -g.sparql("""SELECT (COUNT(?project) as ?p) -WHERE { - ?person v:label "person" . - ?person v:age ?age . FILTER (?age < 30) - ?person e:created ?project . -} GROUP BY (?age) LIMIT 2""") ----- - -==== Meta-Property Access - -Accessing the Meta-Property of a graph element. Meta-Property can be perceived as the reified statements in an RDF -graph. - -[source,groovy] ----- -g = traversal(SparqlTraversalSource).with(graph) -g.sparql("""SELECT ?name ?startTime -WHERE { - ?person v:name "daniel" . - ?person p:location ?location . - ?location v:value ?name . - ?location v:startTime ?startTime }""") ----- - -==== STAR-shaped queries - -STAR-shaped queries are the queries that form/follow a star-shaped execution plan. These in terms of graph traversals -can be perceived as path queries or neighborhood queries. For instance, getting all the information about a specific -`person` or `software`. - -[source,groovy] ----- -g.sparql("""SELECT ?age ?software ?lang ?name -WHERE { - ?person v:name "josh" . - ?person v:age ?age . - ?person e:created ?software . - ?software v:lang ?lang . - ?software v:name ?name . }""") ----- - -[[sparql-with-gremlin]] -=== With Gremlin - -The `sparql()`-step takes a SPARQL query and returns a result. That result can be further processed by standard Gremlin -steps as shown below: - -[source,groovy] ----- -g = traversal(SparqlTraversalSource).with(graph) -g.sparql("SELECT ?name ?age WHERE { ?person v:name ?name . ?person v:age ?age }") -g.sparql("SELECT ?name ?age WHERE { ?person v:name ?name . ?person v:age ?age }").select("name") -g.sparql("SELECT * WHERE { }").out("knows").values("name") -g.withSack(1.0f).sparql("SELECT * WHERE { }"). - repeat(outE().sack(mult).by("weight").inV()). - times(2). - sack() ----- - -Mixing SPARQL with Gremlin steps introduces some interesting possibilities for complex traversals. \ No newline at end of file diff --git a/docs/src/reference/index.asciidoc b/docs/src/reference/index.asciidoc index 80f1112d2a..104dd7c655 100644 --- a/docs/src/reference/index.asciidoc +++ b/docs/src/reference/index.asciidoc @@ -49,7 +49,6 @@ include::implementations-hadoop-start.asciidoc[] include::implementations-spark.asciidoc[] include::implementations-hadoop-end.asciidoc[] -include::compilers.asciidoc[] include::conclusion.asciidoc[] diff --git a/docs/src/reference/intro.asciidoc b/docs/src/reference/intro.asciidoc index 37b54dc0c5..b4cf33536c 100644 --- a/docs/src/reference/intro.asciidoc +++ b/docs/src/reference/intro.asciidoc @@ -45,8 +45,7 @@ image::gremlin-reference.png[width=1024] Despite all this diversity and disparity, Gremlin remains the unifying interface for all these different elements of the graph community. As a user, choosing a TinkerPop-enabled graph and using Gremlin in the correct way when building applications shields them from change and disparity in the space. As a graph provider, choosing to become -TinkerPop-enabled not only expands the reach their system can get into different development ecosystems, but also -provides access to other query languages through bytecode compilation as seen in <<sparql-gremlin,sparql-gremlin>>. +TinkerPop-enabled immediately expands the reach their system can get into different development ecosystems. Irrespective of the programming language being used, graph system chosen or other development background that might be driving a user to this documentation, the critical point to remember is that "Gremlin is Gremlin is Gremlin". The diff --git a/docs/src/upgrade/release-4.x.x.asciidoc b/docs/src/upgrade/release-4.x.x.asciidoc index f0216e0b8d..2df3fbc987 100644 --- a/docs/src/upgrade/release-4.x.x.asciidoc +++ b/docs/src/upgrade/release-4.x.x.asciidoc @@ -214,6 +214,13 @@ Connection(url, traversal_source, executor, pool, Custom transport implementations are no longer supported. The driver uses `AiohttpHTTPTransport` directly. +==== Removal of sparql-gremlin + +The `sparql-gremlin` module has been removed following a prolonged period of inactivity. There is currently no direct +replacement planned for this functionality. + +See: link:https://issues.apache.org/jira/browse/TINKERPOP-3249[TINKERPOP-3249] + ==== Runtime Upgrades The minimum target framework is now `net8.0` (previously `netstandard2.0;net6.0`). .NET 6 reached end-of-life in diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java index c6d29ad432..6e98642d7b 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java @@ -106,7 +106,6 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.stream.Stream; @@ -126,17 +125,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { super(name); } - /** - * Attempt to load {@code SparqlStrategy} if it's on the path. Dynamically loading it from core makes it easier - * for users as they won't have to register special modules for serialization purposes. - */ - private static Optional<Class<?>> tryLoadSparqlStrategy() { - try { - return Optional.of(Class.forName("org.apache.tinkerpop.gremlin.sparql.process.traversal.strategy.SparqlStrategy")); - } catch (Exception ignored) { - return Optional.empty(); - } - } + /** * Version 4.0 of GraphSON. @@ -353,7 +342,6 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { VertexProgramStrategy.class ).forEach(strategy -> put(strategy, strategy.getSimpleName())); - GraphSONModule.tryLoadSparqlStrategy().ifPresent(s -> put(s, s.getSimpleName())); }}); /** @@ -489,7 +477,6 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { VertexProgramStrategy.class ).forEach(strategy -> addDeserializer(strategy, new TraversalSerializersV3.TraversalStrategyProxyJacksonDeserializer(strategy))); - GraphSONModule.tryLoadSparqlStrategy().ifPresent(s -> addDeserializer(s, new TraversalSerializersV3.TraversalStrategyProxyJacksonDeserializer(s))); } public static Builder build() { @@ -601,7 +588,6 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { VertexProgramStrategy.class ).forEach(strategy -> put(strategy, strategy.getSimpleName())); - GraphSONModule.tryLoadSparqlStrategy().ifPresent(s -> put(s, s.getSimpleName())); }}); /** @@ -723,7 +709,6 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { VertexProgramStrategy.class ).forEach(strategy -> addDeserializer(strategy, new TraversalSerializersV2.TraversalStrategyProxyJacksonDeserializer(strategy))); - GraphSONModule.tryLoadSparqlStrategy().ifPresent(s -> addDeserializer(s, new TraversalSerializersV2.TraversalStrategyProxyJacksonDeserializer(s))); } public static Builder build() { diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java index 47fb327323..86f4edd1f0 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java @@ -440,8 +440,7 @@ public enum GryoVersion { tryAddDynamicType(this, "org.apache.tinkerpop.gremlin.util.message.ResponseMessage", "org.apache.tinkerpop.gremlin.util.ser.ResponseMessageGryoSerializer", 169); - tryAddDynamicType(this, "org.apache.tinkerpop.gremlin.sparql.process.traversal.strategy.SparqlStrategy", - null, 184); + // ID 184 was SparqlStrategy - removed in 4.0 }}; } diff --git a/pom.xml b/pom.xml index 57097b37e2..732f644dff 100644 --- a/pom.xml +++ b/pom.xml @@ -138,7 +138,6 @@ limitations under the License. <module>gremlin-go</module> <module>hadoop-gremlin</module> <module>spark-gremlin</module> - <module>sparql-gremlin</module> <module>gremlin-console</module> <module>gremlin-tools</module> </modules> diff --git a/sparql-gremlin/pom.xml b/sparql-gremlin/pom.xml deleted file mode 100644 index 02e6e6ff12..0000000000 --- a/sparql-gremlin/pom.xml +++ /dev/null @@ -1,69 +0,0 @@ -<!-- -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. ---> -<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"> - <modelVersion>4.0.0</modelVersion> - <parent> - <artifactId>tinkerpop</artifactId> - <groupId>org.apache.tinkerpop</groupId> - <version>4.0.0-SNAPSHOT</version> - </parent> - <artifactId>sparql-gremlin</artifactId> - <name>Apache TinkerPop :: SPARQL Gremlin</name> - - <dependencies> - <dependency> - <groupId>org.apache.jena</groupId> - <artifactId>apache-jena-libs</artifactId> - <type>pom</type> - <version>3.12.0</version> - <exclusions> - <exclusion> - <groupId>org.slf4j</groupId> - <artifactId>jcl-over-slf4j</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.apache.tinkerpop</groupId> - <artifactId>gremlin-core</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-classic</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.tinkerpop</groupId> - <artifactId>tinkergraph-gremlin</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest</artifactId> - <scope>test</scope> - </dependency> - </dependencies> -</project> \ No newline at end of file diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/Prefixes.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/Prefixes.java deleted file mode 100644 index c2544e751e..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/Prefixes.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql; - -import java.util.Arrays; -import java.util.List; - -/** - * Helper methods for working with prefix lines in SPARQL queries. - */ -class Prefixes { - - final static String BASE_URI = "http://tinkerpop.apache.org/traversal/"; - - private final static List<String> PREFIXES = Arrays.asList("edge", "property", "value"); - - private final static String PREFIX_DEFINITIONS; - - static { - final StringBuilder builder = new StringBuilder(); - for (final String prefix : PREFIXES) { - builder.append("PREFIX ").append(prefix, 0, 1).append(": <").append(getURI(prefix)). - append(">").append(System.lineSeparator()); - } - PREFIX_DEFINITIONS = builder.toString(); - } - - static String getURI(final String prefix) { - return BASE_URI + prefix + "#"; - } - - static String getURIValue(final String uri) { - return uri.substring(uri.indexOf("#") + 1); - } - - static String getPrefix(final String uri) { - final String tmp = uri.substring(0, uri.indexOf("#")); - return tmp.substring(tmp.lastIndexOf("/") + 1); - } - - static String prepend(final String script) { - return PREFIX_DEFINITIONS + script; - } - - static StringBuilder prepend(final StringBuilder scriptBuilder) { - return scriptBuilder.insert(0, PREFIX_DEFINITIONS); - } -} diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/SparqlToGremlinCompiler.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/SparqlToGremlinCompiler.java deleted file mode 100644 index 62e964729e..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/SparqlToGremlinCompiler.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.SortCondition; -import org.apache.jena.query.Syntax; -import org.apache.jena.sparql.algebra.Algebra; -import org.apache.jena.sparql.algebra.Op; -import org.apache.jena.sparql.algebra.OpVisitorBase; -import org.apache.jena.sparql.algebra.OpWalker; -import org.apache.jena.sparql.algebra.op.OpBGP; -import org.apache.jena.sparql.algebra.op.OpFilter; -import org.apache.jena.sparql.algebra.op.OpLeftJoin; -import org.apache.jena.sparql.algebra.op.OpUnion; -import org.apache.jena.sparql.core.Var; -import org.apache.jena.sparql.core.VarExprList; -import org.apache.jena.sparql.expr.Expr; -import org.apache.jena.sparql.expr.ExprAggregator; -import org.apache.tinkerpop.gremlin.process.traversal.Order; -import org.apache.tinkerpop.gremlin.process.traversal.Scope; -import org.apache.tinkerpop.gremlin.process.traversal.Traversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.Vertex; - -/** - * The engine that compiles SPARQL to Gremlin traversals thus enabling SPARQL to be executed on any TinkerPop-enabled - * graph system. - */ -public class SparqlToGremlinCompiler { - - private GraphTraversal<Vertex, ?> traversal; - - private List<Traversal> traversalList = new ArrayList<>(); - List<Traversal> optionalTraversals = new ArrayList<Traversal>(); - List<String> optionalVariable = new ArrayList<String>(); - boolean optionalFlag = false; - - private SparqlToGremlinCompiler(final GraphTraversal<Vertex, ?> traversal) { - this.traversal = traversal; - } - - private SparqlToGremlinCompiler(final GraphTraversalSource g) { - this(g.V()); - } - - /** - * Converts SPARQL to a Gremlin traversal. - * - * @param graph the {@link Graph} instance to execute the traversal from - * @param sparqlQuery the query to compile to Gremlin - */ - public static GraphTraversal<Vertex, ?> compile(final Graph graph, final String sparqlQuery) { - return compile(graph.traversal(), sparqlQuery); - } - - /** - * Converts SPARQL to a Gremlin traversal. - * - * @param g the {@link GraphTraversalSource} instance to execute the traversal from - * @param sparqlQuery the query to compile to Gremlin - */ - public static GraphTraversal<Vertex, ?> compile(final GraphTraversalSource g, final String sparqlQuery) { - return compile(g, QueryFactory.create(Prefixes.prepend(sparqlQuery), Syntax.syntaxSPARQL)); - } - - private GraphTraversal<Vertex, ?> compile(final Query query) { - final Op op = Algebra.compile(query); - OpWalker.walk(op, new GremlinOpVisitor()); - - int traversalIndex = 0; - final int numberOfTraversal = traversalList.size(); - final int numberOfOptionalTraversal = optionalTraversals.size(); - final Traversal[] arrayOfAllTraversals = (numberOfOptionalTraversal > 0) ? - new Traversal[numberOfTraversal - numberOfOptionalTraversal + 1] : - new Traversal[numberOfTraversal - numberOfOptionalTraversal]; - - final Traversal[] arrayOfOptionalTraversals = new Traversal[numberOfOptionalTraversal]; - - for (Traversal tempTrav : traversalList) { - arrayOfAllTraversals[traversalIndex++] = tempTrav; - } - - traversalIndex = 0; - for (Traversal tempTrav : optionalTraversals) - arrayOfOptionalTraversals[traversalIndex++] = tempTrav; - - // creates a map of ordering keys and their ordering direction - final Map<String, Order> orderingIndex = createOrderIndexFromQuery(query); - - if (traversalList.size() > 0) - traversal = traversal.match(arrayOfAllTraversals); - - if (optionalTraversals.size() > 0) { - traversal = traversal.coalesce(__.match(arrayOfOptionalTraversals), (Traversal) __.constant("N/A")); - for (int i = 0; i < optionalVariable.size(); i++) { - traversal = traversal.as(optionalVariable.get(i).substring(1)); - } - } - - final List<String> vars = query.getResultVars(); - if (!query.isQueryResultStar() && !query.hasGroupBy()) { - final String[] all = new String[vars.size()]; - vars.toArray(all); - if (query.isDistinct()) { - traversal = traversal.dedup(all); - } - - // apply ordering from ORDER BY - orderingIndex.forEach((k, v) -> traversal = traversal.order().by(__.select(k), v)); - - // the result sizes have special handling to get the right signatures of select() called. - switch (all.length) { - case 0: - throw new IllegalStateException(); - case 1: - traversal = traversal.select(all[0]); - break; - case 2: - traversal = traversal.select(all[0], all[1]); - break; - default: - final String[] others = Arrays.copyOfRange(all, 2, vars.size()); - traversal = traversal.select(all[0], all[1], others); - break; - } - } - - if (query.hasGroupBy()) { - final VarExprList lstExpr = query.getGroupBy(); - String grpVar = ""; - for (Var expr : lstExpr.getVars()) { - grpVar = expr.getName(); - } - - if (!grpVar.isEmpty()) - traversal = traversal.select(grpVar); - if (query.hasAggregators()) { - final List<ExprAggregator> exprAgg = query.getAggregators(); - for (ExprAggregator expr : exprAgg) { - if (expr.getAggregator().getName().contains("COUNT")) { - if (!query.toString().contains("GROUP")) { - if (expr.getAggregator().toString().contains("DISTINCT")) - traversal = traversal.dedup(expr.getAggregator().getExprList().get(0).toString().substring(1)); - else - traversal = traversal.select(expr.getAggregator().getExprList().get(0).toString().substring(1)); - - traversal = traversal.count(); - } else { - traversal = traversal.groupCount(); - } - } - if (expr.getAggregator().getName().contains("MAX")) { - traversal = traversal.max(); - } - } - } else { - traversal = traversal.group(); - } - } - - if (query.hasOrderBy() && query.hasGroupBy()) - orderingIndex.forEach((k, v) -> traversal = traversal.order().by(__.select(k), v)); - - if (query.hasLimit()) { - long limit = query.getLimit(), offset = 0; - - if (query.hasOffset()) - offset = query.getOffset(); - - if (query.hasGroupBy() && query.hasOrderBy()) - traversal = traversal.range(Scope.local, offset, offset + limit); - else - traversal = traversal.range(offset, offset + limit); - } - - return traversal; - } - - /** - * Extracts any {@code SortCondition} instances from the SPARQL query and holds them in an index of their keys - * where the value is that keys sorting direction. - */ - private static Map<String, Order> createOrderIndexFromQuery(final Query query) { - final Map<String, Order> orderingIndex = new HashMap<>(); - if (query.hasOrderBy()) { - final List<SortCondition> sortingConditions = query.getOrderBy(); - - for (SortCondition sortCondition : sortingConditions) { - final Expr expr = sortCondition.getExpression(); - - // by default, the sort will be ascending. getDirection() returns -2 if the DESC/ASC isn't - // supplied - weird - orderingIndex.put(expr.getVarName(), sortCondition.getDirection() == -1 ? Order.desc : Order.asc); - } - } - - return orderingIndex; - } - - private static GraphTraversal<Vertex, ?> compile(final GraphTraversalSource g, final Query query) { - return new SparqlToGremlinCompiler(g).compile(query); - } - - /** - * An {@code OpVisitor} implementation that reads SPARQL algebra operations into Gremlin traversals. - */ - private class GremlinOpVisitor extends OpVisitorBase { - - /** - * Visiting triple patterns in SPARQL algebra. - */ - @Override - public void visit(final OpBGP opBGP) { - if(optionalFlag) - { - opBGP.getPattern().getList().forEach(triple -> optionalTraversals.add(TraversalBuilder.transform(triple))); - opBGP.getPattern().getList().forEach(triple -> optionalVariable.add(triple.getObject().toString())); - - } - else - opBGP.getPattern().getList().forEach(triple -> traversalList.add(TraversalBuilder.transform(triple))); - } - - /** - * Visiting filters in SPARQL algebra. - */ - @Override - public void visit(final OpFilter opFilter) { - Traversal traversal; - for (Expr expr : opFilter.getExprs().getList()) { - if (expr != null) { - traversal = __.where(WhereTraversalBuilder.transform(expr)); - traversalList.add(traversal); - } - } - } - - - /** - * Visiting LeftJoin(Optional) in SPARQL algebra. - */ - @Override - public void visit(final OpLeftJoin opLeftJoin) { - optionalFlag = true; - optionalVisit(opLeftJoin.getRight()); - if (opLeftJoin.getExprs() != null) { - for (Expr expr : opLeftJoin.getExprs().getList()) { - if (expr != null) { - if (optionalFlag) - optionalTraversals.add(__.where(WhereTraversalBuilder.transform(expr))); - } - } - } - } - - /** - * Walking OP for Optional in SPARQL algebra. - */ - private void optionalVisit(final Op op) { - - OpWalker.walk(op, this); - } - - /** - * Visiting unions in SPARQL algebra. - */ - @Override - public void visit(final OpUnion opUnion) { - final Traversal unionTemp[] = new Traversal[2]; - final Traversal unionTemp1[] = new Traversal[traversalList.size() / 2]; - final Traversal unionTemp2[] = new Traversal[traversalList.size() / 2]; - - int count = 0; - - for (int i = 0; i < traversalList.size(); i++) { - if (i < traversalList.size() / 2) - unionTemp1[i] = traversalList.get(i); - else - unionTemp2[count++] = traversalList.get(i); - } - - unionTemp[1] = __.match(unionTemp2); - unionTemp[0] = __.match(unionTemp1); - - traversalList.clear(); - traversal = (GraphTraversal<Vertex, ?>) traversal.union(unionTemp); - } - - } -} diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/TraversalBuilder.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/TraversalBuilder.java deleted file mode 100644 index 64315ebd54..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/TraversalBuilder.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql; - -import org.apache.jena.graph.Node; -import org.apache.jena.graph.Triple; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.structure.PropertyType; -import org.apache.tinkerpop.gremlin.structure.Vertex; - -/** - * Converts triple patterns into {@link GraphTraversal} instances. - */ -class TraversalBuilder { - - static GraphTraversal<?, ?> transform(final Triple triple) { - final GraphTraversal<Vertex, ?> matchTraversal = __.as(triple.getSubject().getName()); - - final Node predicate = triple.getPredicate(); - final String uri = predicate.getURI(); - final String uriValue = Prefixes.getURIValue(uri); - final String prefix = Prefixes.getPrefix(uri); - - switch (prefix) { - case "edge": - return matchTraversal.out(uriValue).as(triple.getObject().getName()); - case "property": - return matchProperty(matchTraversal, uriValue, PropertyType.PROPERTY, triple.getObject()); - case "value": - return matchProperty(matchTraversal, uriValue, PropertyType.VALUE, triple.getObject()); - default: - throw new IllegalStateException(String.format("Unexpected predicate: %s", predicate)); - } - } - - private static GraphTraversal<?, ?> matchProperty(final GraphTraversal<?, ?> traversal, final String propertyName, - final PropertyType type, final Node object) { - switch (propertyName) { - case "id": - return object.isConcrete() - ? traversal.hasId(object.getLiteralValue()) - : traversal.id().as(object.getName()); - case "label": - return object.isConcrete() - ? traversal.hasLabel(object.getLiteralValue().toString()) - : traversal.label().as(object.getName()); - case "key": - return object.isConcrete() - ? traversal.hasKey(object.getLiteralValue().toString()) - : traversal.key().as(object.getName()); - case "value": - return object.isConcrete() - ? traversal.hasValue(object.getLiteralValue().toString()) - : traversal.value().as(object.getName()); - default: - if (type.equals(PropertyType.PROPERTY)) { - return traversal.properties(propertyName).as(object.getName()); - } else { - return object.isConcrete() - ? traversal.has(propertyName, object.getLiteralValue()) - : traversal.values(propertyName).as(object.getName()); - } - } - } -} diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/WhereTraversalBuilder.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/WhereTraversalBuilder.java deleted file mode 100644 index f699a6e85c..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/WhereTraversalBuilder.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql; - -import java.util.List; - -import org.apache.jena.graph.Triple; -import org.apache.jena.sparql.algebra.op.OpBGP; -import org.apache.jena.sparql.expr.E_Equals; -import org.apache.jena.sparql.expr.E_Exists; -import org.apache.jena.sparql.expr.E_GreaterThan; -import org.apache.jena.sparql.expr.E_GreaterThanOrEqual; -import org.apache.jena.sparql.expr.E_LessThan; -import org.apache.jena.sparql.expr.E_LessThanOrEqual; -import org.apache.jena.sparql.expr.E_LogicalAnd; -import org.apache.jena.sparql.expr.E_LogicalOr; -import org.apache.jena.sparql.expr.E_NotEquals; -import org.apache.jena.sparql.expr.E_NotExists; -import org.apache.jena.sparql.expr.Expr; -import org.apache.tinkerpop.gremlin.process.traversal.P; -import org.apache.tinkerpop.gremlin.process.traversal.Step; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; - -/** - * Converts SPARQL "where" expressions to Gremlin predicates. - */ -class WhereTraversalBuilder { - - /** - * Converts a general {@code Expr} to an anonymous {@link GraphTraversal}. - */ - static GraphTraversal<?, ?> transform(final Expr expression) { - if (expression instanceof E_Equals) return transform((E_Equals) expression); - if (expression instanceof E_NotEquals) return transform((E_NotEquals) expression); - if (expression instanceof E_LessThan) return transform((E_LessThan) expression); - if (expression instanceof E_LessThanOrEqual) return transform((E_LessThanOrEqual) expression); - if (expression instanceof E_GreaterThan) return transform((E_GreaterThan) expression); - if (expression instanceof E_GreaterThanOrEqual) return transform((E_GreaterThanOrEqual) expression); - if (expression instanceof E_LogicalAnd) return transform((E_LogicalAnd) expression); - if (expression instanceof E_LogicalOr) return transform((E_LogicalOr) expression); - if (expression instanceof E_Exists) return transform((E_Exists) expression); - if (expression instanceof E_NotExists) return transform((E_NotExists) expression); - throw new IllegalStateException(String.format("Unhandled expression: %s", expression)); - } - - private static GraphTraversal<?, ?> transform(final E_Equals expression) { - final Object value = expression.getArg2().getConstant().getNode().getLiteralValue(); - return __.as(expression.getArg1().getVarName()).is(P.eq(value)); - } - - private static GraphTraversal<?, ?> transform(final E_NotEquals expression) { - final Object value = expression.getArg2().getConstant().getNode().getLiteralValue(); - return __.as(expression.getArg1().getVarName()).is(P.neq(value)); - } - - private static GraphTraversal<?, ?> transform(final E_LessThan expression) { - final Object value = expression.getArg2().getConstant().getNode().getLiteralValue(); - return __.as(expression.getArg1().getVarName()).is(P.lt(value)); - } - - private static GraphTraversal<?, ?> transform(final E_LessThanOrEqual expression) { - final Object value = expression.getArg2().getConstant().getNode().getLiteralValue(); - return __.as(expression.getArg1().getVarName()).is(P.lte(value)); - } - - private static GraphTraversal<?, ?> transform(final E_GreaterThan expression) { - final Object value = expression.getArg2().getConstant().getNode().getLiteralValue(); - return __.as(expression.getArg1().getVarName()).is(P.gt(value)); - } - - private static GraphTraversal<?, ?> transform(final E_GreaterThanOrEqual expression) { - final Object value = expression.getArg2().getConstant().getNode().getLiteralValue(); - return __.as(expression.getArg1().getVarName()).is(P.gte(value)); - } - - private static GraphTraversal<?, ?> transform(final E_LogicalAnd expression) { - return __.and( - transform(expression.getArg1()), - transform(expression.getArg2())); - } - - private static GraphTraversal<?, ?> transform(final E_LogicalOr expression) { - return __.or( - transform(expression.getArg1()), - transform(expression.getArg2())); - } - - private static GraphTraversal<?, ?> transform(final E_Exists expression) { - final OpBGP opBGP = (OpBGP) expression.getGraphPattern(); - final List<Triple> triples = opBGP.getPattern().getList(); - if (triples.size() != 1) throw new IllegalStateException("Unhandled EXISTS pattern"); - final GraphTraversal<?, ?> traversal = TraversalBuilder.transform(triples.get(0)); - final Step endStep = traversal.asAdmin().getEndStep(); - final String label = (String) endStep.getLabels().iterator().next(); - endStep.removeLabel(label); - return traversal; - } - - - private static GraphTraversal<?, ?> transform(final E_NotExists expression) { - final OpBGP opBGP = (OpBGP) expression.getGraphPattern(); - final List<Triple> triples = opBGP.getPattern().getList(); - if (triples.size() != 1) throw new IllegalStateException("Unhandled NOT EXISTS pattern"); - final GraphTraversal<?, ?> traversal = TraversalBuilder.transform(triples.get(0)); - final Step endStep = traversal.asAdmin().getEndStep(); - final String label = (String) endStep.getLabels().iterator().next(); - endStep.removeLabel(label); - return __.not(traversal); - } -} \ No newline at end of file diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/jsr223/SparqlGremlinPlugin.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/jsr223/SparqlGremlinPlugin.java deleted file mode 100644 index 76ce26a433..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/jsr223/SparqlGremlinPlugin.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql.jsr223; - -import org.apache.tinkerpop.gremlin.jsr223.AbstractGremlinPlugin; -import org.apache.tinkerpop.gremlin.jsr223.DefaultImportCustomizer; -import org.apache.tinkerpop.gremlin.jsr223.GremlinPlugin; -import org.apache.tinkerpop.gremlin.jsr223.ImportCustomizer; -import org.apache.tinkerpop.gremlin.sparql.process.traversal.dsl.sparql.DefaultSparqlTraversal; -import org.apache.tinkerpop.gremlin.sparql.process.traversal.dsl.sparql.SparqlTraversal; -import org.apache.tinkerpop.gremlin.sparql.process.traversal.dsl.sparql.SparqlTraversalSource; -import org.apache.tinkerpop.gremlin.sparql.process.traversal.strategy.SparqlStrategy; - -/** - * {@link GremlinPlugin} implementation for {@code sparql-gremlin} that imports the key classes and interfaces required - * to use SPARQL in TinkerPop. - * - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -public final class SparqlGremlinPlugin extends AbstractGremlinPlugin { - - private static final String NAME = "tinkerpop.sparql"; - - private static final ImportCustomizer imports; - - static { - try { - imports = DefaultImportCustomizer.build().addClassImports( - SparqlTraversalSource.class, - SparqlTraversal.class, - DefaultSparqlTraversal.class, - SparqlStrategy.class).create(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - private static final SparqlGremlinPlugin instance = new SparqlGremlinPlugin(); - - public SparqlGremlinPlugin() { - super(NAME, imports); - } - - public static SparqlGremlinPlugin instance() { - return instance; - } -} diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/DefaultSparqlTraversal.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/DefaultSparqlTraversal.java deleted file mode 100644 index 3d815237eb..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/DefaultSparqlTraversal.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql.process.traversal.dsl.sparql; - -import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal; -import org.apache.tinkerpop.gremlin.structure.Graph; - -/** - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -public class DefaultSparqlTraversal<S, E> extends DefaultTraversal<S, E> implements SparqlTraversal.Admin<S, E> { - - public DefaultSparqlTraversal() { - super(); - } - - public DefaultSparqlTraversal(final SparqlTraversalSource sparqlTraversalSource) { - super(sparqlTraversalSource); - } - - public DefaultSparqlTraversal(final Graph graph) { - super(graph); - } - - @Override - public SparqlTraversal.Admin<S, E> asAdmin() { - return this; - } - - @Override - public SparqlTraversal<S, E> iterate() { - return SparqlTraversal.Admin.super.iterate(); - } - - @Override - public DefaultSparqlTraversal<S, E> clone() { - return (DefaultSparqlTraversal<S, E>) super.clone(); - } -} diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversal.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversal.java deleted file mode 100644 index 47901cfddc..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversal.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql.process.traversal.dsl.sparql; - -import org.apache.tinkerpop.gremlin.process.traversal.Step; -import org.apache.tinkerpop.gremlin.process.traversal.Traversal; - -/** - * The {@code SparqlTraversal} has no additional traversal steps. The only step available for "SPARQL" is the - * {@link SparqlTraversalSource#sparql(String)} start step. - * - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -public interface SparqlTraversal<S, E> extends Traversal<S, E> { - public interface Admin<S, E> extends Traversal.Admin<S, E>, SparqlTraversal<S, E> { - - @Override - public default <E2> SparqlTraversal.Admin<S, E2> addStep(final Step<?, E2> step) { - return (SparqlTraversal.Admin<S, E2>) Traversal.Admin.super.addStep((Step) step); - } - - @Override - public default SparqlTraversal<S, E> iterate() { - return SparqlTraversal.super.iterate(); - } - - @Override - public SparqlTraversal.Admin<S, E> clone(); - } - - @Override - public default SparqlTraversal.Admin<S, E> asAdmin() { - return (SparqlTraversal.Admin<S, E>) this; - } - - //// - - /** - * Iterates the traversal presumably for the generation of side-effects. - */ - @Override - public default SparqlTraversal<S, E> iterate() { - Traversal.super.iterate(); - return this; - } -} diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversalSource.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversalSource.java deleted file mode 100644 index 6d50ec7f52..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversalSource.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql.process.traversal.dsl.sparql; - -import org.apache.tinkerpop.gremlin.process.computer.Computer; -import org.apache.tinkerpop.gremlin.process.computer.GraphComputer; -import org.apache.tinkerpop.gremlin.process.remote.RemoteConnection; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep; -import org.apache.tinkerpop.gremlin.sparql.process.traversal.strategy.SparqlStrategy; -import org.apache.tinkerpop.gremlin.structure.Graph; - -import java.util.function.BinaryOperator; -import java.util.function.Supplier; -import java.util.function.UnaryOperator; - -/** - * A {@link TraversalSource} implementation that spawns {@link SparqlTraversal} instances. - * - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -public class SparqlTraversalSource extends GraphTraversalSource { - - public SparqlTraversalSource(final Graph graph, final TraversalStrategies traversalStrategies) { - super(graph, traversalStrategies); - } - - public SparqlTraversalSource(final Graph graph) { - super(graph); - } - - public SparqlTraversalSource(final RemoteConnection connection) { - super(connection); - } - - @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException") - public SparqlTraversalSource clone() { - return (SparqlTraversalSource) super.clone(); - } - - //// CONFIGURATIONS - - - @Override - public SparqlTraversalSource with(final String key) { - return (SparqlTraversalSource) super.with(key); - } - - @Override - public SparqlTraversalSource with(final String key, final Object value) { - return (SparqlTraversalSource) super.with(key, value); - } - - @Override - public SparqlTraversalSource withComputer(final Computer computer) { - return (SparqlTraversalSource) super.withComputer(computer); - } - - @Override - public SparqlTraversalSource withComputer(final Class<? extends GraphComputer> graphComputerClass) { - return (SparqlTraversalSource) super.withComputer(graphComputerClass); - } - - @Override - public SparqlTraversalSource withComputer() { - return (SparqlTraversalSource) super.withComputer(); - } - - @Override - public <A> SparqlTraversalSource withSideEffect(final String key, final Supplier<A> initialValue, final BinaryOperator<A> reducer) { - return (SparqlTraversalSource) super.withSideEffect(key, initialValue, reducer); - } - - @Override - public <A> SparqlTraversalSource withSideEffect(final String key, final A initialValue, final BinaryOperator<A> reducer) { - return (SparqlTraversalSource) super.withSideEffect(key, initialValue, reducer); - } - - @Override - public <A> SparqlTraversalSource withSideEffect(final String key, final A initialValue) { - return (SparqlTraversalSource) super.withSideEffect(key, initialValue); - } - - @Override - public <A> SparqlTraversalSource withSideEffect(final String key, final Supplier<A> initialValue) { - return (SparqlTraversalSource) super.withSideEffect(key, initialValue); - } - - @Override - public <A> SparqlTraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) { - return (SparqlTraversalSource) super.withSack(initialValue, splitOperator, mergeOperator); - } - - @Override - public <A> SparqlTraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) { - return (SparqlTraversalSource) super.withSack(initialValue, splitOperator, mergeOperator); - } - - @Override - public <A> SparqlTraversalSource withSack(final A initialValue) { - return (SparqlTraversalSource) super.withSack(initialValue); - } - - @Override - public <A> SparqlTraversalSource withSack(final Supplier<A> initialValue) { - return (SparqlTraversalSource) super.withSack(initialValue); - } - - @Override - public <A> SparqlTraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator) { - return (SparqlTraversalSource) super.withSack(initialValue, splitOperator); - } - - @Override - public <A> SparqlTraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator) { - return (SparqlTraversalSource) super.withSack(initialValue, splitOperator); - } - - @Override - public <A> SparqlTraversalSource withSack(final Supplier<A> initialValue, final BinaryOperator<A> mergeOperator) { - return (SparqlTraversalSource) super.withSack(initialValue, mergeOperator); - } - - @Override - public <A> SparqlTraversalSource withSack(final A initialValue, final BinaryOperator<A> mergeOperator) { - return (SparqlTraversalSource) super.withSack(initialValue, mergeOperator); - } - - @Override - public SparqlTraversalSource withBulk(final boolean useBulk) { - return (SparqlTraversalSource) super.withBulk(useBulk); - } - - @Override - public SparqlTraversalSource withPath() { - return (SparqlTraversalSource) super.withPath(); - } - - @Override - public SparqlTraversalSource withStrategies(final TraversalStrategy... traversalStrategies) { - return (SparqlTraversalSource) super.withStrategies(traversalStrategies); - } - - @Override - @SuppressWarnings({"unchecked"}) - public SparqlTraversalSource withoutStrategies(final Class<? extends TraversalStrategy>... traversalStrategyClasses) { - return (SparqlTraversalSource) super.withoutStrategies(traversalStrategyClasses); - } - - /** - * The start step for a SPARQL based traversal that accepts a string representation of the query to execute. - */ - public <S> GraphTraversal<S,?> sparql(final String query) { - final SparqlTraversalSource clone = this.withStrategies(SparqlStrategy.instance()).clone(); - - // the inject() holds the sparql which the SparqlStrategy then detects and converts to a traversal - clone.gremlinLang.addStep(GraphTraversal.Symbols.inject, query); - final GraphTraversal.Admin<S, S> traversal = new DefaultGraphTraversal(clone); - return traversal.addStep(new InjectStep<>(traversal, query)); - } -} diff --git a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/strategy/SparqlStrategy.java b/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/strategy/SparqlStrategy.java deleted file mode 100644 index 95a8442015..0000000000 --- a/sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/strategy/SparqlStrategy.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql.process.traversal.strategy; - -import org.apache.tinkerpop.gremlin.process.remote.traversal.strategy.decoration.RemoteStrategy; -import org.apache.tinkerpop.gremlin.process.traversal.Traversal; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep; -import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy; -import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper; -import org.apache.tinkerpop.gremlin.sparql.SparqlToGremlinCompiler; -import org.apache.tinkerpop.gremlin.sparql.process.traversal.dsl.sparql.SparqlTraversalSource; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.Vertex; - -import java.util.Collections; -import java.util.Set; - -/** - * This {@link TraversalStrategy} is used in conjunction with the {@link SparqlTraversalSource} which has a single - * {@code sparql()} start step. That step adds a {@link InjectStep} to the traversal with the SPARQL query within - * it as a string value. This strategy finds that step and compiles it to a Gremlin traversal which then replaces - * the {@link InjectStep}. - * - * For remote bytecode execution, note that the {@code sparql-gremlin} dependencies need to be on the server. The - * way remoting works - see {@code RemoteStep} - prevents modified bytecode from being submitted to the server, so - * technically, this strategy can't be applied first on the client. - * - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -public class SparqlStrategy extends AbstractTraversalStrategy<TraversalStrategy.DecorationStrategy> - implements TraversalStrategy.DecorationStrategy { - private static final SparqlStrategy INSTANCE = new SparqlStrategy(); - - private static final Set<Class<? extends DecorationStrategy>> PRIORS = Collections.singleton(RemoteStrategy.class); - - private SparqlStrategy() {} - - public static SparqlStrategy instance() { - return INSTANCE; - } - - @Override - public Set<Class<? extends DecorationStrategy>> applyPrior() { - return PRIORS; - } - - @Override - public void apply(final Traversal.Admin<?, ?> traversal) { - if (!(traversal.isRoot())) - return; - - // assumes that the traversal starts with the single inject step that holds the sparql query - if (traversal.getStartStep() instanceof InjectStep) { - final InjectStep stepWithSparql = (InjectStep) traversal.getStartStep(); - final Object[] injections = stepWithSparql.getInjections(); - - // further assumes that there is just one argument to that injection which is a string (i.e. sparql query) - if (injections.length == 1 && injections[0] instanceof String) { - final String sparql = (String) injections[0]; - - // try to grab the TraversalSource from the Traversal, but if it's not there then try to the Graph - // instance and spawn one off from there. - final Traversal<Vertex, ?> sparqlTraversal = SparqlToGremlinCompiler.compile( - (GraphTraversalSource) traversal.getTraversalSource().orElseGet(() -> traversal.getGraph().map(Graph::traversal).get()), sparql); - TraversalHelper.insertTraversal(stepWithSparql, sparqlTraversal.asAdmin(), traversal); - traversal.removeStep(stepWithSparql); - } - } - } -} diff --git a/sparql-gremlin/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.jsr223.GremlinPlugin b/sparql-gremlin/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.jsr223.GremlinPlugin deleted file mode 100644 index 882054c35e..0000000000 --- a/sparql-gremlin/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.jsr223.GremlinPlugin +++ /dev/null @@ -1 +0,0 @@ -org.apache.tinkerpop.gremlin.sparql.jsr223.SparqlGremlinPlugin \ No newline at end of file diff --git a/sparql-gremlin/src/test/java/org/apache/tinkerpop/gremlin/sparql/PrefixesTest.java b/sparql-gremlin/src/test/java/org/apache/tinkerpop/gremlin/sparql/PrefixesTest.java deleted file mode 100644 index 155680b1c5..0000000000 --- a/sparql-gremlin/src/test/java/org/apache/tinkerpop/gremlin/sparql/PrefixesTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class PrefixesTest { - - final static String TEST_QUERY = String.join(System.lineSeparator(), "SELECT *", "WHERE {}"); - final static String PREFIXED_QUERY = String.join(System.lineSeparator(), - "PREFIX e: <" + Prefixes.BASE_URI + "edge#>", - "PREFIX p: <" + Prefixes.BASE_URI + "property#>", - "PREFIX v: <" + Prefixes.BASE_URI + "value#>", - TEST_QUERY); - - @Test - public void testGetURI() throws Exception { - final String prefix = "test"; - final String uri = Prefixes.BASE_URI + prefix + "#"; - assertEquals(uri, Prefixes.getURI(prefix)); - } - - @Test - public void testGetURIValue() throws Exception { - final String prefix = "test"; - final String value = "value"; - final String uri = Prefixes.getURI(prefix) + value; - assertEquals(value, Prefixes.getURIValue(uri)); - } - - @Test - public void testGetPrefix() throws Exception { - final String prefix = "test"; - final String uri = Prefixes.getURI(prefix); - assertEquals(prefix, Prefixes.getPrefix(uri)); - } - - @Test - public void testPrependString() throws Exception { - assertEquals(PREFIXED_QUERY, Prefixes.prepend(TEST_QUERY)); - } - - @Test - public void testPrependStringBuilder() throws Exception { - final StringBuilder builder = new StringBuilder(TEST_QUERY); - assertEquals(PREFIXED_QUERY, Prefixes.prepend(builder).toString()); - } -} \ No newline at end of file diff --git a/sparql-gremlin/src/test/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversalSourceTest.java b/sparql-gremlin/src/test/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversalSourceTest.java deleted file mode 100644 index 552ac73e49..0000000000 --- a/sparql-gremlin/src/test/java/org/apache/tinkerpop/gremlin/sparql/process/traversal/dsl/sparql/SparqlTraversalSourceTest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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.tinkerpop.gremlin.sparql.process.traversal.dsl.sparql; - -import org.apache.tinkerpop.gremlin.process.traversal.Traversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory; -import org.junit.Test; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.apache.tinkerpop.gremlin.process.traversal.Operator.mult; -import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outE; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; -import static org.hamcrest.collection.IsIterableContainingInOrder.contains; -import static org.junit.Assert.assertEquals; - -/** - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -public class SparqlTraversalSourceTest { - - private static final Graph graph = TinkerFactory.createModern(); - private static final SparqlTraversalSource g = graph.traversal(SparqlTraversalSource.class); - private static final GraphTraversalSource _g = graph.traversal(); - - @Test - public void shouldStartWithSparqlReturningMapAndEndWithGremlin() { - final List<?> x = g.sparql("SELECT ?name ?age WHERE { ?person v:name ?name . ?person v:age ?age }").select("name").toList(); - assertThat(x, containsInAnyOrder("marko", "vadas", "josh", "peter")); - } - - @Test - public void shouldStartWithSparqlReturningVertexAndEndWithGremlin() { - final List<?> x = g.sparql("SELECT * WHERE { }").out("knows").values("name").toList(); - assertThat(x, containsInAnyOrder("vadas", "josh")); - } - - @Test - public void shouldStartWithSparqlUsingSacksAndEndWithGremlin() { - final List<?> x = g.withSack(1.0f).sparql("SELECT * WHERE { }").repeat( - (Traversal) outE().sack(mult).by("weight").inV()).times(2).sack().toList(); - assertThat(x, containsInAnyOrder(1.0, 0.4)); - } - - @Test - public void shouldFindAllPersonsNamesAndAges() { - final List<?> x = g.sparql("SELECT ?name ?age WHERE { ?person v:name ?name . ?person v:age ?age }").toList(); - assertThat(x, containsInAnyOrder( - new HashMap<String,Object>(){{ - put("name", "marko"); - put("age", 29); - }}, - new HashMap<String,Object>(){{ - put("name", "vadas"); - put("age", 27); - }}, - new HashMap<String,Object>(){{ - put("name", "josh"); - put("age", 32); - }}, - new HashMap<String,Object>(){{ - put("name", "peter"); - put("age", 35); - }} - )); - } - - @Test - public void shouldFindAllPersonsNamesAndAgesOrdered() { - final List<?> x = g.sparql("SELECT ?name ?age WHERE { ?person v:name ?name . ?person v:age ?age } ORDER BY ASC(?age)").toList(); - assertThat(x, contains( - new HashMap<String,Object>(){{ - put("name", "vadas"); - put("age", 27); - }}, - new HashMap<String,Object>(){{ - put("name", "marko"); - put("age", 29); - }}, - new HashMap<String,Object>(){{ - put("name", "josh"); - put("age", 32); - }}, - new HashMap<String,Object>(){{ - put("name", "peter"); - put("age", 35); - }} - )); - } - - @Test - public void shouldFindAllNamesOrdered() { - final List<?> x = g.sparql("SELECT ?name WHERE { ?person v:name ?name } ORDER BY DESC(?name)").toList(); - assertThat(x, contains("vadas", "ripple", "peter", "marko", "lop", "josh")); - } - - @Test - public void shouldFilter() { - final Map<String,Vertex> x = (Map) g.sparql( "SELECT ?a ?b ?c\n" + - "WHERE {\n" + - " ?a v:label \"person\" .\n" + - " ?a e:knows ?b .\n" + - " ?a e:created ?c .\n" + - " ?b e:created ?c .\n" + - " ?a v:age ?d .\n" + - " FILTER (?d < 30)\n" + - "}").next(); - - assertEquals(x.get("a"), _g.V(1).next()); - assertEquals(x.get("b"), _g.V(4).next()); - assertEquals(x.get("c"), _g.V(3).next()); - assertEquals(3, x.size()); - } - - @Test - public void shouldFilterMulti() { - final List<String> names = (List<String>) g.sparql( "SELECT DISTINCT ?name\n" + - "WHERE {\n" + - "?person v:label \"person\" .\n" + - "?person v:age ?age .\n" + - "?person e:created ?project .\n" + - "?project v:name ?name .\n" + - "?project v:lang ?lang .\n" + - "FILTER (?age > 30 && ?lang = \"java\") }").toList(); - - assertThat(names, containsInAnyOrder("ripple", "lop")); - } - - @Test - public void shouldDistinct() { - final List<?> x = g.sparql( - "SELECT DISTINCT ?name\n" + - "WHERE {\n" + - " ?a e:created ?b .\n" + - " ?a v:name ?name .\n" + - "}").toList(); - assertThat(x, containsInAnyOrder("marko", "josh", "peter")); - } - - @Test - public void shouldDistinctAndOrder() { - final List<?> x = g.sparql( - "SELECT DISTINCT ?name\n" + - "WHERE {\n" + - " ?a e:created ?b .\n" + - " ?a v:name ?name .\n" + - "}" + - "ORDER BY ?name").toList(); - assertThat(x, contains("josh", "marko", "peter")); - } - - @Test - public void shouldGroup() { - final Map<String,Long> x = (Map) g.sparql( - "SELECT ?name (COUNT(?name) AS ?name_count)\n" + - "WHERE {\n" + - " ?a e:created ?b .\n" + - " ?a v:name ?name .\n" + - "}" + - "GROUP BY ?name").next(); - assertEquals(new Long(2), x.get("josh")); - assertEquals(new Long(1), x.get("peter")); - assertEquals(new Long(1), x.get("marko")); - assertEquals(3, x.size()); - } -} diff --git a/sparql-gremlin/src/test/resources/logback-silent.xml b/sparql-gremlin/src/test/resources/logback-silent.xml deleted file mode 100644 index 4c5947d8ce..0000000000 --- a/sparql-gremlin/src/test/resources/logback-silent.xml +++ /dev/null @@ -1,26 +0,0 @@ -<!-- -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="stdout" class="ch.qos.logback.core.ConsoleAppender"> - <encoder> - <pattern>[%p] %C - %m%n</pattern> - </encoder> - </appender> - <root level="OFF"> - <appender-ref ref="stdout"/> - </root> -</configuration> \ No newline at end of file diff --git a/sparql-gremlin/src/test/resources/logback-test.xml b/sparql-gremlin/src/test/resources/logback-test.xml deleted file mode 100644 index 5d94c3bca2..0000000000 --- a/sparql-gremlin/src/test/resources/logback-test.xml +++ /dev/null @@ -1,26 +0,0 @@ -<!-- -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="stdout" class="ch.qos.logback.core.ConsoleAppender"> - <encoder> - <pattern>[%p] %C - %m%n</pattern> - </encoder> - </appender> - <root level="WARN"> - <appender-ref ref="stdout"/> - </root> -</configuration> \ No newline at end of file
