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 <[email protected]>
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 }"); }
-//
-//}

Reply via email to