This is an automated email from the ASF dual-hosted git repository.
afs pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/main by this push:
new 0aa9feeafd GH-4091: Make quads a 1st class results format
0aa9feeafd is described below
commit 0aa9feeafdd77f3fbe01768413979146cdc5c5d1
Author: Andy Seaborne <[email protected]>
AuthorDate: Mon Jul 27 21:46:01 2026 +0100
GH-4091: Make quads a 1st class results format
---
.../jena/sparql/resultset/ResultsFormat.java | 154 +++++++++++----------
.../apache/jena/sparql/util/QueryExecUtils.java | 10 +-
.../apache/jena/sparql/resultset/TS_ResultSet.java | 1 +
.../jena/sparql/resultset/TestResultsFormat.java | 73 ++++++++++
4 files changed, 157 insertions(+), 81 deletions(-)
diff --git
a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultsFormat.java
b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultsFormat.java
index 1ac7b520e7..141bdf322e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultsFormat.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultsFormat.java
@@ -28,49 +28,57 @@ import org.apache.jena.riot.resultset.ResultSetLang;
import org.apache.jena.sparql.util.TranslationTable;
/**
- * The output formats for all query types.
- * Result sets, boolean graphs.
+ * The output formats for all query types. This allows the APi to given a
results
+ * choice before the kind of query is known.
* <p>
- * This does not include results sets as RDF. They are provided for tests
with {@link RDFInput} and {@link RDFOutput}.
+ * This does not include results sets as RDF. They are provided for tests with
+ * {@link RDFInput} and {@link RDFOutput}.
+ * <p>
+ * A {@code ResultsFormat} item has three parts, result format, triples format
(e.g.
+ * CONSTRUCT), and quads (for extended CONSTRUCT). These are stored in a
lookup table
+ * for string to {@code ResultsFormat}, which is used by commands.
*/
public enum ResultsFormat {
- // Results formats, by surface syntax.
- // Used by commands.
+ // Does not cover boolean results.
- XML(ResultSetLang.RS_XML, RDFFormat.RDFXML_ABBREV),
- JSON(ResultSetLang.RS_JSON, RDFFormat.JSONLD11),
- TEXT(ResultSetLang.RS_Text, RDFFormat.TURTLE),
+ XML(ResultSetLang.RS_XML, RDFFormat.RDFXML_ABBREV, null),
+ JSON(ResultSetLang.RS_JSON, RDFFormat.JSONLD, RDFFormat.JSONLD),
+ TEXT(ResultSetLang.RS_Text, RDFFormat.TURTLE, RDFFormat.TRIG),
- CSV(ResultSetLang.RS_CSV, null),
- TSV(ResultSetLang.RS_TSV, null),
+ CSV(ResultSetLang.RS_CSV, null, null),
+ TSV(ResultSetLang.RS_TSV, null, null),
- THRIFT(ResultSetLang.RS_Thrift, RDFFormat.RDF_THRIFT),
- PROTOBUF(ResultSetLang.RS_Protobuf, RDFFormat.RDF_PROTO),
+ THRIFT(ResultSetLang.RS_Thrift, RDFFormat.RDF_THRIFT,
RDFFormat.RDF_THRIFT),
+ PROTOBUF(ResultSetLang.RS_Protobuf, RDFFormat.RDF_PROTO,
RDFFormat.RDF_PROTO),
// result set as RDF is handled specially
- TTL(null, RDFFormat.TURTLE),
- NT(null, RDFFormat.NTRIPLES),
- RDFXML(null, RDFFormat.RDFXML),
- RDF_JSONLD(null, RDFFormat.JSONLD),
+ TTL(null, RDFFormat.TURTLE, null),
+ NT(null, RDFFormat.NTRIPLES, null),
+
+ TRIG(null, RDFFormat.TRIG, RDFFormat.TRIG),
+ NQ(null, RDFFormat.NQUADS, RDFFormat.NQUADS),
+
+ RDFXML(null, RDFFormat.RDFXML, null),
+ JSONLD(null, RDFFormat.JSONLD, RDFFormat.JSONLD),
// Special name.
- COUNT(null, null),
+ COUNT(null, null, null),
- NONE(ResultSetLang.RS_None, RDFFormat.RDFNULL),
+ NONE(ResultSetLang.RS_None, RDFFormat.RDFNULL, RDFFormat.RDFNULL),
- SSE(null, null),
- TUPLES(null, null)
- ;
+ SSE(null, null, null)
+ ;
private final Lang resultSetLang;
- private final RDFFormat rdfFormat;
+ private final RDFFormat triplesFormat;
+ private final RDFFormat quadsFormat;
//private final boolean supportsBoolean;
- private ResultsFormat(Lang resultSetLang, RDFFormat rdfFormat) {
+ private ResultsFormat(Lang resultSetLang, RDFFormat triplesFormat,
RDFFormat quadsFormat) {
this.resultSetLang = resultSetLang;
- this.rdfFormat = rdfFormat;
-
+ this.triplesFormat = triplesFormat;
+ this.quadsFormat = quadsFormat;
//this.supportsBoolean = supportsBoolean;
}
@@ -78,18 +86,21 @@ public enum ResultsFormat {
return resultSetLang;
}
- public RDFFormat rdfFormat() {
- return rdfFormat;
+ public RDFFormat triplesFormat() {
+ return triplesFormat;
+ }
+
+ public RDFFormat quadsFormat() {
+ return quadsFormat;
}
-//
// public boolean supportsBoolean() {
// return supportsBoolean;
// }
-//
-// public boolean isResultSet() {
-// return ResultSetLang.isRegistered(lang());
-// }
+
+ public boolean isResultSet() {
+ return ResultSetLang.isRegistered(resultSetLang);
+ }
/** Guess the syntax of a result set URL */
public static ResultsFormat guessSyntax(String resultsFilename) {
@@ -107,7 +118,7 @@ public enum ResultsFormat {
}
/**
- * Look up a short name for a result set FMT_
+ * Look up a short name for an output format.
*
* @param shortname Short name
* @return ResultSetFormat
@@ -117,59 +128,50 @@ public enum ResultsFormat {
}
// Common names to symbol (used by arq.rset)
- private static TranslationTable<ResultsFormat> names = new
TranslationTable<>(true) ;
+ private static TranslationTable<ResultsFormat> names = new
TranslationTable<>(true);
static {
- names.put("srx", XML) ;
- names.put("xml", XML) ;
+ names.put("srx", XML);
+ names.put("srj", JSON);
+ names.put("srt", THRIFT);
+ names.put("srp", PROTOBUF);
+ names.put("srpb", PROTOBUF);
+
+ names.put("rt", THRIFT);
+ names.put("trdf", THRIFT);
- names.put("json", JSON) ;
- names.put("srj", JSON) ;
+ names.put("rpb", PROTOBUF);
+ names.put("pbrdf", PROTOBUF);
- names.put("srt", THRIFT) ;
- names.put("srp", PROTOBUF) ;
+ names.put("rdfxml", RDFXML);
- names.put("rdfxml", RDFXML) ;
- names.put("rdf", TTL) ;
+ names.put("xml", XML);
+ names.put("json", JSON);
+
+ names.put("rdf", TTL);
names.put("ttl", TTL);
names.put("turtle", TTL);
+ names.put("trig", TRIG);
+
names.put("n-triples", NT);
names.put("ntriples", NT);
names.put("nt", NT);
- // Thrift/RDF
- // Protobuf/RDF
-
-
- names.put("jsonld", RDF_JSONLD) ;
- names.put("json-ld", RDF_JSONLD) ;
-
- names.put("sse", SSE) ;
- names.put("csv", CSV) ;
- names.put("tsv", TSV) ;
- names.put("text", TEXT) ;
- names.put("count", COUNT) ;
- names.put("tuples", TUPLES) ;
- names.put("none", NONE) ;
-
- //names.put("rdf", ???) ;
-
-// names.put("rdf", RDF_XML) ;
-// names.put("rdf/n3", RDF_N3) ;
-// names.put("rdf/xml", RDF_XML) ;
-// names.put("n3", RDF_N3) ;
-// names.put("ttl", RDF_TTL) ;
-// names.put("turtle", RDF_TTL) ;
-// names.put("graph", RDF_TTL) ;
-// names.put("nt", RDF_NT) ;
-// names.put("n-triples", RDF_NT) ;
-// names.put("ntriples", RDF_NT) ;
-// names.put("jsonld", RDF_JSONLD) ;
-// names.put("json-ld", RDF_JSONLD) ;
-//
-// names.put("nq", RDF_NQ) ;
-// names.put("nquads", RDF_NQ) ;
-// names.put("n-quads", RDF_NQ) ;
-// names.put("trig", RDF_TRIG) ;
+ names.put("n-quads", NQ);
+ names.put("nquads", NQ);
+ names.put("nq", NQ);
+
+ names.put("jsonld", JSONLD);
+ names.put("json-ld", JSONLD);
+
+ names.put("sse", SSE);
+ names.put("csv", CSV);
+ names.put("tsv", TSV);
+
+ names.put("text", TEXT);
+ names.put("txt", TEXT);
+ names.put("count", COUNT);
+
+ names.put("none", NONE);
}
}
diff --git
a/jena-arq/src/main/java/org/apache/jena/sparql/util/QueryExecUtils.java
b/jena-arq/src/main/java/org/apache/jena/sparql/util/QueryExecUtils.java
index b8acdd21a6..0d58de5c19 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/QueryExecUtils.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/QueryExecUtils.java
@@ -201,7 +201,7 @@ public class QueryExecUtils {
Lang rsLang = outputFormat.resultSetLang();
if ( rsLang == null ) {
- RDFFormat asRDF = outputFormat.rdfFormat();
+ RDFFormat asRDF = outputFormat.triplesFormat();
Model model = RDFOutput.encodeAsModel(resultSet);
RDFWriter.source(model).format(asRDF).output(output);
return;
@@ -260,7 +260,7 @@ public class QueryExecUtils {
Lang rsLang = outputFormat.resultSetLang();
if ( rsLang == null ) {
- RDFFormat asRDF = outputFormat.rdfFormat();
+ RDFFormat asRDF = outputFormat.triplesFormat();
Model model = RDFOutput.encodeAsModel(resultBoolean);
RDFWriter.source(model).format(asRDF).output(output);
return;
@@ -270,15 +270,15 @@ public class QueryExecUtils {
}
private static void writeModel(Model model, ResultsFormat outputFormat,
OutputStream output) {
- RDFFormat rdfFormat = RDFFormat.TURTLE_PRETTY;
+ RDFFormat rdfFormat = outputFormat.triplesFormat();
RDFWriter.source(model).format(rdfFormat).output(output);
return;
}
private static void writeDataset(Dataset dataset, ResultsFormat
outputFormat, OutputStream output) {
- RDFFormat rdfFormat = outputFormat.rdfFormat();
+ RDFFormat rdfFormat = outputFormat.quadsFormat();
if ( rdfFormat == null )
- throw noFormatException("No dataset output format for :
"+outputFormat.name());
+ throw noFormatException("No dataset output format for:
"+outputFormat.name());
RDFWriter.source(dataset).format(rdfFormat).output(output);
return;
}
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 f0d13db30c..3abf8e04b6 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
@@ -29,6 +29,7 @@ import org.junit.platform.suite.api.Suite;
TestResultSet.class
, TestResultSetWriting.class
, TestResultSetParsing.class
+ , TestResultsFormat.class
})
public class TS_ResultSet
{
diff --git
a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultsFormat.java
b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultsFormat.java
new file mode 100644
index 0000000000..91b822636d
--- /dev/null
+++
b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultsFormat.java
@@ -0,0 +1,73 @@
+/*
+ * 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
+ *
+ * https://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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.apache.jena.sparql.resultset;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import org.junit.jupiter.api.Test;
+
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFFormat;
+import org.apache.jena.riot.resultset.ResultSetLang;
+
+public class TestResultsFormat {
+
+ @Test public void entry_srj() { test("srj", ResultsFormat.JSON,
ResultSetLang.RS_JSON, RDFFormat.JSONLD, RDFFormat.JSONLD); }
+ @Test public void entry_srx() { test("srx", ResultsFormat.XML,
ResultSetLang.RS_XML, RDFFormat.RDFXML, null); }
+
+ @Test public void entry_ttl1() { test("ttl", ResultsFormat.TTL, null,
RDFFormat.TURTLE, null); }
+ @Test public void entry_ttl2() { test("turtle", ResultsFormat.TTL,
null, RDFFormat.TURTLE, null); }
+
+ @Test public void entry_nt1() { test("nt", ResultsFormat.NT, null,
RDFFormat.NTRIPLES, null); }
+ @Test public void entry_nt2() { test("n-triples", ResultsFormat.NT,
null, RDFFormat.NTRIPLES, null); }
+
+ @Test public void entry_trig1() { test("trig", ResultsFormat.TRIG,
null, RDFFormat.TRIG, RDFFormat.TRIG); }
+
+ @Test public void entry_nq1() { test("NQ", ResultsFormat.NQ, null,
RDFFormat.NQUADS, RDFFormat.NQUADS); }
+ @Test public void entry_nq2() { test("n-quads", ResultsFormat.NQ,
null, RDFFormat.NQUADS, RDFFormat.NQUADS); }
+
+ @Test public void entry_text1() { test("text", ResultsFormat.TEXT,
ResultSetLang.RS_Text, RDFFormat.TURTLE, RDFFormat.TRIG); }
+ @Test public void entry_text2() { test("txt", ResultsFormat.TEXT,
ResultSetLang.RS_Text, RDFFormat.TURTLE, RDFFormat.TRIG); }
+ @Test public void entry_text3() { test("TXT", ResultsFormat.TEXT,
ResultSetLang.RS_Text, RDFFormat.TURTLE, RDFFormat.TRIG); }
+
+ @Test public void entry_xml() { test("xml", ResultsFormat.XML,
ResultSetLang.RS_XML, RDFFormat.RDFXML, null); }
+ @Test public void entry_rdfxml() { test("rdfxml", ResultsFormat.RDFXML,
null, RDFFormat.RDFXML, null); }
+
+ @Test public void entry_json() { test("json", ResultsFormat.JSON,
ResultSetLang.RS_JSON, RDFFormat.JSONLD, RDFFormat.JSONLD); }
+ @Test public void entry_jsonld() { test("jsonld", ResultsFormat.JSONLD,
null, RDFFormat.JSONLD, RDFFormat.JSONLD); }
+
+ @Test public void entry_bad() { testBad("SHACL"); }
+
+ private void test(String string, ResultsFormat expected, Lang rsLang,
RDFFormat triplesFormat, RDFFormat quadsFormat) {
+ ResultsFormat rFmt = ResultsFormat.lookup(string);
+ assertEquals(expected, rFmt);
+ assertEquals(rsLang, rFmt.resultSetLang());
+ assertEquals(triplesFormat, rFmt.triplesFormat());
+ assertEquals(quadsFormat, rFmt.quadsFormat());
+ }
+
+ private void testBad(String string) {
+ ResultsFormat rFmt = ResultsFormat.lookup(string);
+ assertNull(rFmt);
+ }
+}