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
The following commit(s) were added to refs/heads/main by this push:
new 66862b2679 GH-3501: Updates for Titanium 1.7.0
66862b2679 is described below
commit 66862b26795b1c351e0f327f7399d26c722186f6
Author: Andy Seaborne <[email protected]>
AuthorDate: Wed Oct 8 09:28:32 2025 +0100
GH-3501: Updates for Titanium 1.7.0
---
.../org/apache/jena/riot/lang/LangJSONLD11.java | 9 +-
.../org/apache/jena/riot/system/JenaTitanium.java | 67 ++++++-----
.../apache/jena/riot/writer/JsonLD11Writer.java | 128 ++++++++++++++++-----
.../org/apache/jena/riot/lang/TestLangJsonLD.java | 8 +-
.../org/apache/jena/system/TestJenaTitanium.java | 2 +-
pom.xml | 2 +-
6 files changed, 152 insertions(+), 64 deletions(-)
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/lang/LangJSONLD11.java
b/jena-arq/src/main/java/org/apache/jena/riot/lang/LangJSONLD11.java
index d960bdb2e7..fe1cea703c 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/lang/LangJSONLD11.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/lang/LangJSONLD11.java
@@ -20,6 +20,7 @@ package org.apache.jena.riot.lang;
import java.io.InputStream;
import java.io.Reader;
+import java.net.URI;
import java.util.Set;
import java.util.function.BiConsumer;
@@ -29,7 +30,6 @@ import com.apicatalog.jsonld.JsonLdOptions;
import com.apicatalog.jsonld.document.Document;
import com.apicatalog.jsonld.document.JsonDocument;
import com.apicatalog.jsonld.lang.Keywords;
-import com.apicatalog.rdf.RdfDataset;
import com.apicatalog.rdf.api.RdfConsumerException;
import com.apicatalog.rdf.api.RdfQuadConsumer;
@@ -114,7 +114,6 @@ public class LangJSONLD11 implements ReaderRIOT {
private void read(Document document, String baseURI, StreamRDF output,
Context context) throws JsonLdError {
// JSON-LD to RDF
JsonLdOptions opts = getJsonLdOptions(baseURI, context);
- RdfDataset dataset =
JsonLd.toRdf(document).options(opts).base(baseURI).get();
extractPrefixes(document, output::prefix);
RdfQuadConsumer consumer = new JsonLDToStreamRDF(output, profile);
@@ -234,7 +233,11 @@ public class LangJSONLD11 implements ReaderRIOT {
*/
private static JsonLdOptions getJsonLdOptions(String baseURI, Context
jenaContext) {
JsonLdOptions opts = jenaContext.get(JSONLD_OPTIONS);
- return (opts != null) ? opts : new JsonLdOptions();
+ if ( opts == null )
+ opts = new JsonLdOptions();
+ if ( baseURI != null )
+ opts.setBase(URI.create(baseURI));
+ return opts;
}
static class JsonLDToStreamRDF implements RdfQuadConsumer {
diff --git
a/jena-arq/src/main/java/org/apache/jena/riot/system/JenaTitanium.java
b/jena-arq/src/main/java/org/apache/jena/riot/system/JenaTitanium.java
index 7c9f4cf95d..ee0fa0b595 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/JenaTitanium.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/JenaTitanium.java
@@ -34,7 +34,12 @@ import org.apache.jena.sparql.core.DatasetGraphFactory;
import org.apache.jena.sparql.core.Quad;
import org.apache.jena.sparql.util.NodeUtils;
-/** Conversion to/from Titanium JSON-LD objects */
+
+/**
+/** Conversion to Titanium JSON-LD.
+ * @deprecated To be removed (not needed for Titanium 1.7.0, which introduces
titanium-rdf-primitives)
+ */
+@Deprecated(forRemoval = true)
public class JenaTitanium {
public static class JenaTitaniumException extends JenaException {
@@ -43,7 +48,9 @@ public class JenaTitanium {
/**
* Translate a Jena {@link DatasetGraph} to a Titanium JSON-LD dataset
+ * @deprecated due to changes introduced in Titanium 1.7.0.
*/
+ @Deprecated(forRemoval = true)
public static RdfDataset convert(DatasetGraph dataset) {
RdfProvider provider = RdfProvider.provider();
RdfDataset rdfDataset = provider.createDataset();
@@ -66,6 +73,30 @@ public class JenaTitanium {
return rdfDataset;
}
+ private static RdfResource resource(RdfProvider provider, NodeToLabel
labelMapping, Node node) {
+ if ( node.isBlank() ) {
+ String s = labelMapping.get(null, node);
+ return provider.createBlankNode(s);
+ }
+
+ if ( node.isURI() )
+ return provider.createIRI(node.getURI());
+ throw new JenaTitaniumException("Can not convert to an RdfResource :
"+node);
+ }
+
+ private static RdfValue nodeToValue(RdfProvider provider, NodeToLabel
labelMapping, Node node) {
+ if ( node.isBlank() || node.isURI() )
+ return resource(provider, labelMapping, node);
+
+ if ( node.isLiteral()) {
+ String lex = node.getLiteralLexicalForm();
+ if ( NodeUtils.hasLang(node) )
+ return provider.createLangString(lex,
node.getLiteralLanguage());
+ return provider.createTypedString(lex,
node.getLiteralDatatypeURI());
+ }
+ throw new JenaTitaniumException("Can not be converted: "+node);
+ }
+
/**
* Translate a Titanium JSON-LD dataset to a {@link DatasetGraph}
* @deprecated No longer used by the LangJSONLD_11
@@ -80,7 +111,9 @@ public class JenaTitanium {
/**
* Translate a Titanium JSON-LD dataset to a {@link DatasetGraph}
+ * @deprecated No longer used by the LangJSONLD_11
*/
+ @Deprecated(forRemoval = true)
public static DatasetGraph convert(RdfDataset dataset) {
DatasetGraph dsg = DatasetGraphFactory.createTxnMem();
StreamRDF dest = StreamRDFLib.dataset(dsg);
@@ -89,15 +122,19 @@ public class JenaTitanium {
}
/**
- * Translate a Titanium JSON-LD dataset to a {@link StreamRDF}
+ * Translate a Titanium JSON-LD dataset and output to a {@link StreamRDF}
+ * @deprecated No longer used by the LangJSONLD_11
*/
+ @Deprecated(forRemoval = true)
public static void convert(RdfDataset dataset, StreamRDF output) {
convert(dataset, RiotLib.dftProfile(), output);
}
/**
- * Translate a Titanium JSON-LD dataset to a {@link StreamRDF}.
+ * Translate a Titanium JSON-LD dataset and output to a {@link StreamRDF}
+ * @deprecated No longer used by the LangJSONLD_11
*/
+ @Deprecated(forRemoval = true)
public static void convert(RdfDataset dataset, ParserProfile
parserProfile, StreamRDF output) {
for ( RdfNQuad rdfQuad : dataset.toList() ) {
Optional<RdfResource> gn = rdfQuad.getGraphName();
@@ -147,28 +184,4 @@ public class JenaTitanium {
}
throw new JenaTitaniumException("Not recognized: "+value);
}
-
- private static RdfResource resource(RdfProvider provider, NodeToLabel
labelMapping, Node node) {
- if ( node.isBlank() ) {
- String s = labelMapping.get(null, node);
- return provider.createBlankNode(s);
- }
-
- if ( node.isURI() )
- return provider.createIRI(node.getURI());
- throw new JenaTitaniumException("Can not convert to an RdfResource :
"+node);
- }
-
- private static RdfValue nodeToValue(RdfProvider provider, NodeToLabel
labelMapping, Node node) {
- if ( node.isBlank() || node.isURI() )
- return resource(provider, labelMapping, node);
-
- if ( node.isLiteral()) {
- String lex = node.getLiteralLexicalForm();
- if ( NodeUtils.hasLang(node) )
- return provider.createLangString(lex,
node.getLiteralLanguage());
- return provider.createTypedString(lex,
node.getLiteralDatatypeURI());
- }
- throw new JenaTitaniumException("Can not be converted: "+node);
- }
}
diff --git
a/jena-arq/src/main/java/org/apache/jena/riot/writer/JsonLD11Writer.java
b/jena-arq/src/main/java/org/apache/jena/riot/writer/JsonLD11Writer.java
index 4821de2c6d..9b4d261474 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/writer/JsonLD11Writer.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/JsonLD11Writer.java
@@ -27,30 +27,30 @@ import java.util.Objects;
import com.apicatalog.jsonld.JsonLd;
import com.apicatalog.jsonld.JsonLdError;
import com.apicatalog.jsonld.JsonLdOptions;
+import com.apicatalog.jsonld.JsonLdVersion;
import com.apicatalog.jsonld.api.CompactionApi;
import com.apicatalog.jsonld.document.Document;
import com.apicatalog.jsonld.document.JsonDocument;
-import com.apicatalog.jsonld.document.RdfDocument;
import com.apicatalog.jsonld.lang.Keywords;
-import com.apicatalog.jsonld.processor.FromRdfProcessor;
-import com.apicatalog.rdf.RdfDataset;
+import com.apicatalog.jsonld.serialization.QuadsToJsonld;
+import com.apicatalog.rdf.api.RdfConsumerException;
import jakarta.json.*;
import jakarta.json.stream.JsonGenerator;
import org.apache.jena.atlas.lib.Lib;
import org.apache.jena.atlas.logging.FmtLog;
+import org.apache.jena.graph.Node;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFFormat;
import org.apache.jena.riot.RDFFormatVariant;
import org.apache.jena.riot.WriterDatasetRIOT;
-import org.apache.jena.riot.system.JenaTitanium;
import org.apache.jena.riot.system.PrefixMap;
import org.apache.jena.shared.JenaException;
import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.core.Quad;
import org.apache.jena.sparql.util.Context;
public class JsonLD11Writer implements WriterDatasetRIOT {
-
// It does not matter what the non-null value of PRETTY_PRINTING is (it
could be "false"!).
// It is the keys presence that matters.
private static Map<String, ?> configIndented =
Map.of(JsonGenerator.PRETTY_PRINTING, true);
@@ -62,10 +62,6 @@ public class JsonLD11Writer implements WriterDatasetRIOT {
this.format = format;
}
- private Map<String, ?> config(boolean indented) {
- return indented ? configIndented : configFlat;
- }
-
@Override
public void write(OutputStream outputStream, DatasetGraph datasetGraph,
PrefixMap prefixMap, String baseURI, Context context) {
Objects.requireNonNull(outputStream);
@@ -85,26 +81,30 @@ public class JsonLD11Writer implements WriterDatasetRIOT {
return format.getLang();
}
+ // Write JSON-LD
+
+ static class JenaTitaniumException extends JenaException {
+ JenaTitaniumException(String msg) { super(msg); }
+ }
+
private void write$(OutputStream output, Writer writer, DatasetGraph dsg) {
try {
- // Context, including prefixes.
- RdfDataset ds = JenaTitanium.convert(dsg);
- Document doc = RdfDocument.of(ds);
+ JsonArray array = datasetToJSON(dsg);
+
RDFFormatVariant variant = format.getVariant();
- // We do not write top-level arrays.
JsonStructure writeThis;
boolean indented = true;
// Choose algorithms
if ( Lib.equals(variant, RDFFormat.PRETTY) ) {
- writeThis = writePretty(doc, dsg);
+ writeThis = writePretty(array, dsg);
} else if ( variant == null || Lib.equals(variant,
RDFFormat.PLAIN) ) {
- writeThis = writePlain(doc, dsg);
+ writeThis = writePlain(array, dsg);
} else if ( Lib.equals(variant, RDFFormat.FLAT) ) {
- writeThis = writePlain(doc, dsg);
+ writeThis = writePlain(array, dsg);
indented = false;
} else {
- writeThis = writePretty(doc, dsg);
+ writeThis = writePretty(array, dsg);
}
if ( writeThis == null ) {
@@ -116,29 +116,85 @@ public class JsonLD11Writer implements WriterDatasetRIOT {
FmtLog.warn(this.getClass(), "Output is not a JSON object
(%s)", writeThis.getClass().getSimpleName());
}
- JsonWriter jsonWriter = startWrite(output, writer, indented);
- jsonWriter.write(writeThis);
- finishWrite(output, writer, indented);
+ writeJson(writeThis, output, writer, indented);
} catch (Throwable ex) {
throw new JenaException("Exception while writing JSON-LD 1.1", ex);
}
}
+ /** Jena DatasetGraph to JSON(LD), Titanium QuadsToJsonld in version
1.7.0. */
+ private static JsonArray datasetToJSON(DatasetGraph dsg) throws
JsonLdError {
+ QuadsToJsonld consumer = JsonLd.fromRdf();
+ consumer.mode(JsonLdVersion.V1_1);
+ dsg.stream().forEach( quad->{
+ String s = resource(quad.getSubject());
+ String p = resource(quad.getPredicate());
+ String g = resourceGraphName(quad.getGraph());
+ Node obj = quad.getObject();
+
+ if ( obj.isURI() || obj.isBlank() ) {
+ String o = resource(obj);
+ try {
+ consumer.quad(s, p, o, null, null, null, g);
+ } catch (RdfConsumerException e) {
+ e.printStackTrace();
+ }
+ } else if ( obj.isLiteral() ) {
+ String lex = obj.getLiteralLexicalForm();
+ String datatype = obj.getLiteralDatatypeURI();
+ String lang = obj.getLiteralLanguage();
+ if ( lang.isEmpty() )
+ lang = null;
+ String dir = null;
+ if ( obj.getLiteralBaseDirection() != null )
+ dir = obj.getLiteralBaseDirection().toString();
+ try {
+ consumer.quad(s, p, lex, datatype, lang, dir, g);
+ } catch (RdfConsumerException ex) {
+ throw new JenaException("Exception while translating to
JSON-LD", ex);
+ }
+ } else if ( obj.isTripleTerm() ) {
+ throw new JenaTitaniumException("Triple terms not supported
for JSON-LD");
+ } else {
+ throw new JenaTitaniumException("Encountered unexpected term:
"+obj);
+ }
+ });
+
+ JsonArray array = consumer.toJsonLd();
+ return array;
+ }
+
+ private static String resourceGraphName(Node gn) {
+ if ( gn == null || Quad.isDefaultGraph(gn) )
+ return null;
+ return resource(gn);
+ }
+
+ private static String resource(Node term) {
+ if ( term.isBlank() )
+ return "_:"+term.getBlankNodeLabel();
+ if ( term.isURI() )
+ return term.getURI();
+ throw new JenaTitaniumException("Not a URI or a blank node");
+ }
+
+ private Map<String, ?> config(boolean indented) {
+ return indented ? configIndented : configFlat;
+ }
+
// Plain - no @context.
- private JsonStructure writePlain(Document doc, DatasetGraph dsg) throws
JsonLdError {
- JsonArray array = JsonLd.fromRdf(doc).get();
+ private JsonStructure writePlain(JsonArray array, DatasetGraph dsg) throws
JsonLdError {
JsonObject writeRdf = Json.createObjectBuilder()
.add(Keywords.GRAPH, array)
.build();
return writeRdf;
}
- private JsonStructure writePretty(Document doc, DatasetGraph dsg) throws
JsonLdError {
+ private JsonStructure writePretty(JsonArray array, DatasetGraph dsg)
throws JsonLdError {
JsonLdOptions options = new JsonLdOptions();
// Native types.
// This looses information -- xsd:int becomes xsd:integer, xsd:double
becomes xsd:decimal
// options.setUseNativeTypes(true);
- JsonArray array = FromRdfProcessor.fromRdf(doc, options);
// Build context
JsonObjectBuilder cxt = Json.createObjectBuilder();
@@ -172,12 +228,6 @@ public class JsonLD11Writer implements WriterDatasetRIOT {
return x;
}
- private JsonWriter startWrite(OutputStream output, Writer writer, boolean
indented) {
- Map<String,?> config = config(indented);
- JsonWriterFactory factory = Json.createWriterFactory(config);
- return (output != null ) ? factory.createWriter(output) :
factory.createWriter(writer);
- }
-
/*
* if (pretty) {
Map<String, Boolean> config = new HashMap<>();
@@ -195,6 +245,24 @@ public class JsonLD11Writer implements WriterDatasetRIOT {
}
*/
+ // JsonWriter
+
+
+ private void writeJson(JsonStructure json, OutputStream output, Writer
writer, boolean indented) throws IOException {
+ JsonWriter jw = startWrite(output, writer, true);
+ try {
+ jw.write(json);
+ } finally {
+ finishWrite(output, writer, true);
+ }
+ }
+
+ private JsonWriter startWrite(OutputStream output, Writer writer, boolean
indented) {
+ Map<String,?> config = config(indented);
+ JsonWriterFactory factory = Json.createWriterFactory(config);
+ return (output != null ) ? factory.createWriter(output) :
factory.createWriter(writer);
+ }
+
private void finishWrite(OutputStream output, Writer writer, boolean
indented) throws IOException {
boolean outputNL = indented;
if ( output != null ) {
diff --git
a/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLangJsonLD.java
b/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLangJsonLD.java
index 9805892f89..4e16f7b68d 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLangJsonLD.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLangJsonLD.java
@@ -18,6 +18,7 @@
package org.apache.jena.riot.lang;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -62,10 +63,13 @@ public class TestLangJsonLD {
// "@type": "RelType",
// "http://example/p": { "@id" : "#frag" }
// }
- String jsonld = "{ '@id': './relative', '@type': 'RelType',
'http://example/p': { '@id' : '#frag' } }";
- jsonld = jsonld.replaceAll("'", "\"");
+
+ String jsonld = """
+ { "@id": "./relative", "@type": "RelType", "http://example/p":
{ "@id" : "#frag" } }
+ """;
Graph g = RDFParser.fromString(jsonld,
Lang.JSONLD).base("http://base/abc").toGraph();
assertNotNull(g);
+ assertFalse(g.isEmpty());
Triple t = SSE.parseTriple("( <http://base/relative>
<http://example/p> <http://base/abc#frag> )");
assertTrue(g.contains(t));
}
diff --git
a/jena-arq/src/test/java/org/apache/jena/system/TestJenaTitanium.java
b/jena-arq/src/test/java/org/apache/jena/system/TestJenaTitanium.java
index f1caf80976..1ed5738bd8 100644
--- a/jena-arq/src/test/java/org/apache/jena/system/TestJenaTitanium.java
+++ b/jena-arq/src/test/java/org/apache/jena/system/TestJenaTitanium.java
@@ -42,6 +42,7 @@ import org.apache.jena.sparql.core.Quad;
import org.apache.jena.sparql.sse.SSE;
import org.apache.jena.sparql.util.IsoMatcher;
+@SuppressWarnings({"removal", "deprecation"})
public class TestJenaTitanium {
@Test
@@ -97,7 +98,6 @@ public class TestJenaTitanium {
// Check the RdfDataset
try ( StringWriter writer = new StringWriter() ) {
- @SuppressWarnings("deprecation")
RdfWriter w = new com.apicatalog.rdf.io.nquad.NQuadsWriter(writer);
w.write(rdfDataset);
String s = writer.toString();
diff --git a/pom.xml b/pom.xml
index 985358dd0d..26d31e8111 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,7 +63,7 @@
<ver.log4j2>2.25.2</ver.log4j2>
<!-- JSON-LD 1.1 -->
- <ver.titanium-json-ld>1.6.0</ver.titanium-json-ld>
+ <ver.titanium-json-ld>1.7.0</ver.titanium-json-ld>
<ver.jakarta.json>2.0.1</ver.jakarta.json>
<!-- These two must be in-step -->