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 389f458afc6ba6f6962fcccf70c0c57955cf1f16 Author: Andy Seaborne <[email protected]> AuthorDate: Tue Mar 10 11:43:41 2026 +0000 Update CSV & TSV results for triple terms --- .../jena/riot/rowset/rw/RowSetWriterCSV.java | 11 +++++---- .../apache/jena/sparql/util/NodeFactoryExtra.java | 28 +++++++++++++++++++--- .../jena/riot/resultset/TestResultSetIO.java | 14 +++++++++-- .../apache/jena/sparql/resultset/TS_ResultSet.java | 4 ++-- ...ltSetFormat2.java => TestResultSetParsing.java} | 2 +- ...ltSetFormat1.java => TestResultSetWriting.java} | 26 ++++++++++---------- 6 files changed, 61 insertions(+), 24 deletions(-) diff --git a/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetWriterCSV.java b/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetWriterCSV.java index 615700022a..d8b5eee45d 100644 --- a/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetWriterCSV.java +++ b/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetWriterCSV.java @@ -40,6 +40,7 @@ import org.apache.jena.sparql.engine.binding.Binding; import org.apache.jena.sparql.exec.RowSet; import org.apache.jena.sparql.resultset.ResultSetException; import org.apache.jena.sparql.util.Context; +import org.apache.jena.sparql.util.FmtUtils; public class RowSetWriterCSV implements RowSetWriter { @@ -125,8 +126,8 @@ public class RowSetWriterCSV implements RowSetWriter { } private static void output(AWriter w, Node n, NodeToLabel bnodes) { - // String str = FmtUtils.stringForNode(n) ; - String str = "?"; + String str; + // Without quotes. if ( n.isLiteral() ) str = n.getLiteralLexicalForm(); else if ( n.isURI() ) @@ -134,9 +135,11 @@ public class RowSetWriterCSV implements RowSetWriter { else if ( n.isBlank() ) { str = bnodes.get(null, n); // Comes with leading "_:" - str = str.substring(2); + } else if ( n.isTripleTerm() ) { + str = FmtUtils.stringForNode(n) ; + } else { + str = "?"; } - str = csvSafe(str); w.write(str); w.flush(); diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeFactoryExtra.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeFactoryExtra.java index 3a74b18056..00d55f820f 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeFactoryExtra.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeFactoryExtra.java @@ -27,11 +27,13 @@ import org.apache.jena.atlas.lib.DateTimeUtils ; import org.apache.jena.datatypes.xsd.XSDDatatype ; import org.apache.jena.graph.Node ; import org.apache.jena.graph.NodeFactory ; +import org.apache.jena.graph.Triple; import org.apache.jena.graph.impl.LiteralLabel ; import org.apache.jena.riot.RiotException ; import org.apache.jena.riot.system.PrefixMap ; import org.apache.jena.riot.system.Prefixes; import org.apache.jena.riot.tokens.Token ; +import org.apache.jena.riot.tokens.TokenType; import org.apache.jena.riot.tokens.Tokenizer ; import org.apache.jena.riot.tokens.TokenizerText; import org.apache.jena.sparql.sse.SSE ; @@ -68,15 +70,24 @@ public class NodeFactoryExtra { */ public static Node parseNode(String nodeString, PrefixMap pmap) { Tokenizer tokenizer = TokenizerText.create().fromString(nodeString).build(); + Node node = parseNode(nodeString, tokenizer, pmap); + if ( tokenizer.hasNext() ) + throw new RiotException("Trailing characters in string: " + nodeString) ; + return node; + } + + private static Node parseNode(String nodeString, Tokenizer tokenizer, PrefixMap pmap) { if ( !tokenizer.hasNext() ) throw new RiotException("Empty RDF term") ; Token token = tokenizer.next() ; + if ( token.hasType(TokenType.L_TRIPLE) ) { + // Triple term. + Node n = parseTripleTerm(nodeString, tokenizer, pmap); + return n; + } Node node = token.asNode(pmap) ; if ( node == null ) throw new RiotException("Bad RDF Term: " + nodeString) ; - - if ( tokenizer.hasNext() ) - throw new RiotException("Trailing characters in string: " + nodeString) ; if ( node.isURI() ) { // Lightly test for bad URIs. String x = node.getURI() ; @@ -86,6 +97,17 @@ public class NodeFactoryExtra { return node ; } + private static Node parseTripleTerm(String nodeString, Tokenizer tokenizer, PrefixMap pmap) { + Node s = parseNode(nodeString, tokenizer, pmap); + Node p = parseNode(nodeString, tokenizer, pmap); + Node o = parseNode(nodeString, tokenizer, pmap); + Token tok = tokenizer.next(); + if ( ! tok.hasType(TokenType.R_TRIPLE) ) + throw new RiotException("Bad triple term: " + nodeString) ; + Triple t = Triple.create(s, p, o); + return NodeFactory.createTripleTerm(t); + } + /** * Node to int * diff --git a/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java b/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java index 6eeaec367e..2ff6831faf 100644 --- a/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java +++ b/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java @@ -110,8 +110,18 @@ public class TestResultSetIO { ResultSetMgr.write(out2, rsw, lang); rsw.reset(); in = new ByteArrayInputStream(out2.toByteArray()); - ResultSet rs2 = ResultSetMgr.read(in, lang); - assertTrue(ResultsCompare.equalsByTerm(rsw, rs2)); + ResultSetRewindable rsw2 = ResultSetMgr.read(in, lang).rewindable(); + +// if ( ! ResultsCompare.equalsByTerm(rsw, rsw2) ) { +// ResultSetMgr.write(System.out, rsw, ResultSetLang.RS_JSON); +// System.out.println("--"); +// ResultSetMgr.write(System.out, rsw2, ResultSetLang.RS_JSON); +// } + + rsw.reset(); + rsw2.reset(); + + assertTrue(ResultsCompare.equalsByTerm(rsw, rsw2)); } } diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TS_ResultSet.java b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TS_ResultSet.java index 757ddea7dd..f0d13db30c 100644 --- a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TS_ResultSet.java +++ b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TS_ResultSet.java @@ -27,8 +27,8 @@ import org.junit.platform.suite.api.Suite; @Suite @SelectClasses({ TestResultSet.class - , TestResultSetFormat1.class - , TestResultSetFormat2.class + , TestResultSetWriting.class + , TestResultSetParsing.class }) public class TS_ResultSet { diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat2.java b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetParsing.java similarity index 99% rename from jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat2.java rename to jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetParsing.java index 6009c7bf19..4106bf8534 100644 --- a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat2.java +++ b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetParsing.java @@ -43,7 +43,7 @@ import org.apache.jena.sparql.exec.RowSet; import org.apache.jena.sparql.util.Context; import org.apache.jena.sys.JenaSystem; -public class TestResultSetFormat2 { +public class TestResultSetParsing { static { JenaSystem.init(); } diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetWriting.java similarity index 92% rename from jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java rename to jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetWriting.java index 05a0ecc35a..f3863b6233 100644 --- a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java +++ b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetWriting.java @@ -25,8 +25,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.util.Arrays; -import java.util.Collection; import java.util.List; import java.util.stream.Stream; @@ -54,7 +52,7 @@ import org.apache.jena.vocabulary.XSD; @ParameterizedClass @MethodSource("provideArgs") -public class TestResultSetFormat1 +public class TestResultSetWriting { static { JenaSystem.init(); } @@ -100,7 +98,7 @@ public class TestResultSetFormat1 """ +" (row (?x <" + RDF.type.toString() + ">))\n" +" (row (?x <" + RDFS.label.toString() + ">))\n" - +" (row (?x <" + XSD.integer.toString() + ">))\n" + +" (row (?x <" + XSD.integer.toString() + ">))\n" +" (row (?x <" + OWL.sameAs.toString() + ">))\n" +""" (row ) @@ -111,7 +109,7 @@ public class TestResultSetFormat1 static String $rs8 = """ (resultset (?x) - (row (?x \"has \\t tab character\")) + (row (?x "has \\t tab character")) ) """; @@ -123,28 +121,32 @@ public class TestResultSetFormat1 static String $rs10 = """ (resultset (?x) - (row (?x \"Includes a raw tab character\")) + (row (?x "Includes a raw tab character")) ) """; static String $rs11 = """ (resultset (?x) - (row (?x \"Includes \\n new line\")) + (row (?x "Includes \\n new line")) ) """; + static String $rs12 = "(resultset (?x) (row (?x 'abc'@en--ltr)) )"; + + static String $rs13 = """ + (resultset (?x) + (row (?x <<( <x:s> <x:p> <x:o> )>> )) + ) + """; + private static Stream<Arguments> provideArgs() { List<Arguments> x = List.of(Arguments.of($rs0), Arguments.of($rs1), Arguments.of($rs2), Arguments.of($rs3), Arguments.of($rs4), Arguments.of($rs5), Arguments.of($rs6), Arguments.of($rs7), Arguments.of($rs8), Arguments.of($rs9), - Arguments.of($rs10), Arguments.of($rs11)); + Arguments.of($rs10), Arguments.of($rs11), Arguments.of($rs12), Arguments.of($rs13) ); return x.stream(); } - public static Collection<Object[]> data() { - return Arrays.asList(new Object[][] { {$rs0}, {$rs1}, {$rs2}, {$rs3}, {$rs4}, {$rs5}, {$rs6}, {$rs7}, {$rs8}, {$rs9}, {$rs10}, {$rs11} } ); - } - @Parameter(0) String $rs;
