You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2025/04/25 13:52:41 UTC
(jena) 04/04: GH-3146: VERSION for RIOT Turtle
This is an automated email from the ASF dual-hosted git repository.
andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
commit bd97ad4cf731ade857926787dd2df735644a354b
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Thu Apr 24 10:54:51 2025 +0100
GH-3146: VERSION for RIOT Turtle
---
.../org/apache/jena/riot/lang/LangTurtleBase.java | 51 +++++++-
.../java/org/apache/jena/riot/system/RiotLib.java | 3 -
.../org/apache/jena/riot/system/StreamRDF.java | 2 +-
.../apache/jena/rdf12/basic/TS_RDFStar_Basic.java | 3 +-
.../apache/jena/rdf12/basic/TestSPARQL12Parse.java | 144 +++++++++++++++++++++
.../jena/rdf12/basic/TestSPARQLStarParse.java | 143 --------------------
6 files changed, 190 insertions(+), 156 deletions(-)
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/lang/LangTurtleBase.java b/jena-arq/src/main/java/org/apache/jena/riot/lang/LangTurtleBase.java
index 1b1d017f41..2cbde02649 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/lang/LangTurtleBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/lang/LangTurtleBase.java
@@ -25,6 +25,7 @@ import org.apache.jena.graph.NodeFactory;
import org.apache.jena.riot.system.ParserProfile;
import org.apache.jena.riot.system.PrefixMap;
import org.apache.jena.riot.system.StreamRDF;
+import org.apache.jena.riot.tokens.StringType;
import org.apache.jena.riot.tokens.Token;
import org.apache.jena.riot.tokens.TokenType;
import org.apache.jena.riot.tokens.Tokenizer;
@@ -73,12 +74,13 @@ public abstract class LangTurtleBase extends LangBase {
while (moreTokens()) {
Token t = peekToken();
if ( lookingAt(DIRECTIVE) ) {
- directive(); // @form.
+ directiveAtWord(); // @form.
continue;
}
if ( lookingAt(KEYWORD) ) {
- if ( t.getImage().equalsIgnoreCase("PREFIX") || t.getImage().equalsIgnoreCase("BASE") ) {
+ String text = t.getImage();
+ if ( text.equalsIgnoreCase("PREFIX") || text.equalsIgnoreCase("BASE") || text.equalsIgnoreCase("VERSION") ) {
directiveKeyword();
continue;
}
@@ -95,11 +97,12 @@ public abstract class LangTurtleBase extends LangBase {
protected abstract void oneTopLevelElement();
/**
- * Emit a triple - nodes have been checked as has legality of
- * node type in location.
+ * Emit a triple - nodes have been checked as has the
+ * legality of node type in location.
*/
protected abstract void emit(Node subject, Node predicate, Node object);
+ // Directive, keyword form.
protected final void directiveKeyword() {
Token t = peekToken();
String x = t.getImage();
@@ -114,15 +117,20 @@ public abstract class LangTurtleBase extends LangBase {
directivePrefix();
return;
}
+
+ if ( x.equalsIgnoreCase("VERSION") ) {
+ directiveVersion();
+ return;
+ }
+
exception(t, "Unrecognized keyword for directive: %s", x);
}
- protected final void directive() {
- // It's a directive ...
+ // Directive, @-form.
+ protected final void directiveAtWord() {
Token t = peekToken();
String x = t.getImage();
nextToken();
-
if ( x.equals("base") ) {
directiveBase();
if ( isStrictMode() )
@@ -142,6 +150,15 @@ public abstract class LangTurtleBase extends LangBase {
skipIf(DOT);
return;
}
+ if ( x.equals("version") ) {
+ directiveVersion();
+ if ( isStrictMode() )
+ // The line number is probably one ahead due to the newline
+ expect("Prefix directive not terminated by a dot", DOT);
+ else
+ skipIf(DOT);
+ return;
+ }
exception(t, "Unrecognized directive: %s", x);
}
@@ -173,6 +190,22 @@ public abstract class LangTurtleBase extends LangBase {
nextToken();
}
+ protected final void directiveVersion() {
+ Token token = peekToken();
+ // Single quoted string only.
+ StringType stringType = token.getStringType();
+ switch(stringType) {
+ case STRING1, STRING2 ->{}
+ case LONG_STRING1, LONG_STRING2 ->
+ exception(token, "Triple-quoted strings not allowed for the version string");
+ default ->
+ exception(token, "Expected a single-quoted string for the version setting (found '" + token + "')");
+ }
+ String versionStr = token.getImage();
+ emitVersion(versionStr);
+ nextToken();
+ }
+
// [8] triples ::= subject predicateObjectList
// | blankNodePropertyList predicateObjectList?
// | reifiedTriple predicateObjectList?
@@ -767,6 +800,10 @@ public abstract class LangTurtleBase extends LangBase {
dest.base(baseStr);
}
+ private final void emitVersion(String versionStr) {
+ dest.version(versionStr) ;
+ }
+
protected final Node tokenAsNode(Token token) {
return profile.create(currentGraph, token);
}
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java b/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
index bb3f4b8de9..01c7eef99f 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
@@ -43,8 +43,6 @@ import org.apache.jena.irix.IRIxResolver;
import org.apache.jena.query.ARQ;
import org.apache.jena.riot.*;
import org.apache.jena.riot.lang.LabelToNode;
-import org.apache.jena.riot.out.quoted.QuotedStringOutput;
-import org.apache.jena.riot.out.quoted.QuotedStringOutputNT;
import org.apache.jena.riot.writer.DirectiveStyle;
import org.apache.jena.riot.writer.WriterGraphRIOTBase;
import org.apache.jena.sparql.core.DatasetGraph;
@@ -395,7 +393,6 @@ public class RiotLib {
out.println();
}
- private static final QuotedStringOutput quotedStringProc = new QuotedStringOutputNT();
/**
* Write a version.
* Write using {@code version} or {@code VERSION}.
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/StreamRDF.java b/jena-arq/src/main/java/org/apache/jena/riot/system/StreamRDF.java
index 0ec800d74a..5b92380b05 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/StreamRDF.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/StreamRDF.java
@@ -48,7 +48,7 @@ public interface StreamRDF
public void prefix(String prefix, String iri) ;
/** version declaration seen */
- public void version(String version);
+ public default void version(String version) {}
/** Finish processing */
public void finish() ;
diff --git a/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TS_RDFStar_Basic.java b/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TS_RDFStar_Basic.java
index 5753d8a4d6..34a8682a38 100644
--- a/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TS_RDFStar_Basic.java
+++ b/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TS_RDFStar_Basic.java
@@ -29,8 +29,7 @@ import org.junit.runners.Suite;
TestNTriplesStarParse.class,
TestTrigStarParse.class,
TestTurtleStarParse.class,
-
-// TestSPARQLStarParse.class,
+ TestSPARQL12Parse.class
})
public class TS_RDFStar_Basic {
}
diff --git a/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TestSPARQL12Parse.java b/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TestSPARQL12Parse.java
new file mode 100644
index 0000000000..40e1922338
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TestSPARQL12Parse.java
@@ -0,0 +1,144 @@
+/*
+ * 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.jena.rdf12.basic;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.jena.atlas.lib.StrUtils;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryFactory;
+import org.apache.jena.query.QueryParseException;
+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.OpAsQuery;
+import org.apache.jena.sparql.algebra.op.OpBGP;
+import org.apache.jena.sparql.core.BasicPattern;
+import org.apache.jena.sys.JenaSystem;
+import org.apache.jena.vocabulary.RDF;
+import org.junit.Test;
+
+// RDF Star CG tests, converted to SPARQL 1.2
+
+public class TestSPARQL12Parse {
+
+ static { JenaSystem.init(); }
+
+ // See also testing/ARQ/Syntax/Syntax-ARQ
+ private static final String PREFIXES = StrUtils.strjoinNL
+ ("PREFIX rdf: <"+RDF.getURI()+">"
+ ,"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
+ ,"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>"
+ ,"PREFIX : <http://example/>"
+ ,""
+ );
+
+ private static Query parse(String string) {
+ Query query = QueryFactory.create(PREFIXES+"SELECT * "+string, Syntax.syntaxARQ);
+ return query;
+ }
+
+ private static void parseVars(String string, String... varNames) {
+ Query query = parse(string);
+
+ List<String> vars = query.getResultVars();
+ assertEquals("Wrong number of variables: "+Arrays.asList(varNames)+" : query: "+vars, varNames.length, vars.size());
+ for ( String v : varNames )
+ assertTrue("Expected variable ?"+v, vars.contains(v));
+ }
+
+ @Test public void parse_good_1() { parse("{ << :s :p :o >> :q 456 }"); }
+
+ @Test public void parse_good_2() { parse("{ ?X :q << ?s ?p 123 >> }"); }
+
+ @Test public void parse_good_3() { parse("{ << ?s ?p 123 >> :q << ?s ?p 123 >> }"); }
+
+ @Test public void parse_good_4() { parse("{ << << :s :p 12 >> ?p << :s :p 34 >> >> :q << ?s ?p 123 >> }"); }
+
+ @Test public void parse_vars_1() { parseVars("{ ?X :q << ?s ?p 123 >> }", "X", "s", "p"); }
+
+ @Test public void parse_vars_2() { parseVars("{ ?X :q << ?s :p <<:s :q ?q>> >> }", "X", "s", "q"); }
+
+ // Test structures created.
+ @Test public void build_1() {
+ Triple t = build1("{ <<( :s :p :o )>> :q 456 }");
+ assertTrue(t.isConcrete());
+ assertTrue(t.getSubject().isTripleTerm());
+ }
+
+ @Test public void build_2() {
+ Triple t = build1("{ :x :q <<( :a :b <<( :s ?p :o )>> )>> }");
+ assertFalse(t.isConcrete());
+ assertTrue(t.getObject().isTripleTerm());
+ assertTrue(t.getObject().getTriple().getObject().isTripleTerm());
+ }
+
+ @Test public void build_3() {
+ Triple t = build1("{ <<( :s ?p :o )>> :q 456 }");
+ assertFalse(t.isConcrete());
+ assertTrue(t.getSubject().isTripleTerm());
+ }
+
+ // OpAsQuery
+ @Test public void queryToOpToQuery_1() {
+ queryToOpToQuery("{ << :s :p :o >> :q 456 }");
+ }
+
+ @Test public void queryToOpToQuery_2() {
+ queryToOpToQuery("{ << ?s ?p ?o >> :q 456 }");
+ }
+
+ @Test public void queryToOpToQuery_3() {
+ queryToOpToQuery("{ << << :s :p ?x2 >> ?p << :s :p ?x2 >> >> :q << ?s ?p 123 >> }");
+ }
+
+ private static void queryToOpToQuery(String string) {
+ Query query = parse(string);
+ Op op = Algebra.compile(query);
+ query.getPrefixMapping().clearNsPrefixMap();
+ Query query2 = OpAsQuery.asQuery(op);
+ assertEquals(query, query2);
+ }
+
+ private static Triple build1(String string) {
+ Query query = parse(string);
+ Op op = Algebra.compile(query);
+ BasicPattern bgp = ((OpBGP)op).getPattern();
+ assertEquals(1, bgp.size());
+ Triple t = bgp.get(0);
+ return t ;
+ }
+
+
+ @Test
+ public void reifier_declaration() { parse("{ <<:s :p :o>> }"); }
+
+ @Test(expected=QueryParseException.class)
+ public void parse_bad_2() { parse("{ ?X << :s :p 123 >> ?Z }"); }
+
+ @Test(expected=QueryParseException.class)
+ public void parse_bad_3() { parse("{ << :subject << :s :p 12 >> :object >> :q 123 }"); }
+
+}
diff --git a/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TestSPARQLStarParse.java b/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TestSPARQLStarParse.java
deleted file mode 100644
index 99bd5e1a21..0000000000
--- a/jena-arq/src/test/java/org/apache/jena/rdf12/basic/TestSPARQLStarParse.java
+++ /dev/null
@@ -1,143 +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.jena.rdf12.basic;
-
-public class TestSPARQLStarParse {}
-
-//import static org.junit.Assert.assertEquals;
-//import static org.junit.Assert.assertFalse;
-//import static org.junit.Assert.assertTrue;
-//
-//import java.util.Arrays;
-//import java.util.List;
-//
-//import org.apache.jena.atlas.lib.StrUtils;
-//import org.apache.jena.graph.Triple;
-//import org.apache.jena.query.Query;
-//import org.apache.jena.query.QueryFactory;
-//import org.apache.jena.query.QueryParseException;
-//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.OpAsQuery;
-//import org.apache.jena.sparql.algebra.op.OpBGP;
-//import org.apache.jena.sparql.core.BasicPattern;
-//import org.apache.jena.vocabulary.RDF;
-//import org.junit.Test;
-//
-//// RDF Star CG tests
-//
-//public class TestSPARQLStarParse {
-//
-// // See also testing/ARQ/Syntax/Syntax-ARQ
-// private static final String PREFIXES = StrUtils.strjoinNL
-// ("PREFIX rdf: <"+RDF.getURI()+">"
-// ,"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
-// ,"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>"
-// ,"PREFIX : <http://example/>"
-// ,""
-// );
-//
-// private static Query parse(String string) {
-// Query query = QueryFactory.create(PREFIXES+"SELECT * "+string, Syntax.syntaxARQ);
-// return query;
-// }
-//
-// private static void parseVars(String string, String... varNames) {
-// Query query = parse(string);
-//
-// List<String> vars = query.getResultVars();
-// assertEquals("Wrong number of variables: "+Arrays.asList(varNames)+" : query: "+vars, varNames.length, vars.size());
-// for ( String v : varNames )
-// assertTrue("Expected variable ?"+v, vars.contains(v));
-// }
-//
-// @Test public void parse_good_1() { parse("{ << :s :p :o >> :q 456 }"); }
-//
-// @Test public void parse_good_2() { parse("{ ?X :q << ?s ?p 123 >> }"); }
-//
-// @Test public void parse_good_3() { parse("{ << ?s ?p 123 >> :q << ?s ?p 123 >> }"); }
-//
-// @Test public void parse_good_4() { parse("{ << << :s :p 12 >> ?p << :s :p 34 >> >> :q << ?s ?p 123 >> }"); }
-//
-// @Test public void parse_vars_1() { parseVars("{ ?X :q << ?s ?p 123 >> }", "X", "s", "p"); }
-//
-// @Test public void parse_vars_2() { parseVars("{ ?X :q << ?s :p <<:s :q ?q>> >> }", "X", "s", "q"); }
-//
-// // Test structures created.
-// @Test public void build_1() {
-// Triple t = build("{ << :s :p :o >> :q 456 }");
-// assertTrue(t.isConcrete());
-// assertTrue(t.getSubject().isTripleTerm());
-// }
-//
-// @Test public void build_2() {
-// Triple t = build("{ :x :q << <<:s ?p :o>> :p 678 >> }");
-// assertFalse(t.isConcrete());
-// assertTrue(t.getObject().isTripleTerm());
-// assertTrue(t.getObject().getTriple().getSubject().isTripleTerm());
-// }
-//
-// @Test public void build_3() {
-// Triple t = build("{ << :s ?p :o >> :q 456 }");
-// assertFalse(t.isConcrete());
-// assertTrue(t.getSubject().isTripleTerm());
-// }
-//
-// // OpAsQuery
-// @Test public void queryToOpToQuery_1() {
-// queryToOpToQuery("{ << :s :p :o >> :q 456 }");
-// }
-//
-// @Test public void queryToOpToQuery_2() {
-// queryToOpToQuery("{ << ?s ?p ?o >> :q 456 }");
-// }
-//
-// @Test public void queryToOpToQuery_3() {
-// queryToOpToQuery("{ << << :s :p ?x2 >> ?p << :s :p ?x2 >> >> :q << ?s ?p 123 >> }");
-// }
-//
-// private static void queryToOpToQuery(String string) {
-// Query query = parse(string);
-// Op op = Algebra.compile(query);
-// query.getPrefixMapping().clearNsPrefixMap();
-// Query query2 = OpAsQuery.asQuery(op);
-// assertEquals(query, query2);
-// }
-//
-// private static Triple build(String string) {
-// Query query = parse(string);
-// Op op = Algebra.compile(query);
-// BasicPattern bgp = ((OpBGP)op).getPattern();
-// assertEquals(1, bgp.size());
-// Triple t = bgp.get(0);
-// return t ;
-// }
-//
-//
-// @Test(expected=QueryParseException.class)
-// public void parse_bad_1() { parse("{ <<:s :p :o>> }"); }
-//
-// @Test(expected=QueryParseException.class)
-// public void parse_bad_2() { parse("{ ?X << :s :p 123 >> ?Z }"); }
-//
-// @Test(expected=QueryParseException.class)
-// public void parse_bad_3() { parse("{ << :subject << :s :p 12 >> :object >> :q 123 }"); }
-//
-//}