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 }"); } -// -//}
