This guide explains the functionalities of the jelly-rdf4j module, which provides Jelly support for Eclipse RDF4J.
If you just want to add Jelly format support to your RDF4J application, you can use the Jelly-JVM plugin JAR. See the dedicated guide for more information.
jelly-rdf4j implements an RDF writer and parser for Eclipse RDF4J's Rio library. This means you can use Jelly just like any other RDF serialization format (e.g., RDF/XML, Turtle). See the example below:
packageeu.ostrzyciel.jelly.examplesimporteu.ostrzyciel.jelly.convert.rdf4j.rio.*importeu.ostrzyciel.jelly.core.*importeu.ostrzyciel.jelly.core.proto.v1.{PhysicalStreamType,RdfStreamOptions}importorg.eclipse.rdf4j.model.Statementimportorg.eclipse.rdf4j.rio.helpers.StatementCollectorimportorg.eclipse.rdf4j.rio.{RDFFormat,Rio}importjava.io.{File,FileOutputStream}importscala.jdk.CollectionConverters.*importscala.util.Using/** * Example of using RDF4J's Rio library to read and write RDF data. * * See also: https://rdf4j.org/documentation/programming/rio/ */objectRdf4jRioextendsshared.Example:defmain(args:Array[String]):Unit=// Load the RDF graph from an N-Triples filevalinputFile=File(getClass.getResource("/weather.nt").toURI)valtriples=readRdf4j(inputFile,RDFFormat.TURTLE,None)// Print the size of the graphprintln(s"Loaded ${triples.size} triples from an N-Triples file")// Write the RDF graph to a Jelly file// Fist, create the stream's options:valoptions=JellyOptions.smallStrict// Setting the physical stream type is mandatory! It will always be either TRIPLES or QUADS..withPhysicalType(PhysicalStreamType.TRIPLES)// Set other optional options.withStreamName("My weather data")// Create the config object to pass to the writervalconfig=JellyWriterSettings.configFromOptions(options,frameSize=128)// Do the actual writingUsing.resource(newFileOutputStream("weather.jelly")){out=>valwriter=Rio.createWriter(JELLY,out)writer.setWriterConfig(config)writer.startRDF()triples.foreach(writer.handleStatement)writer.endRDF()}println("Saved the model to a Jelly file")// Load the RDF graph from the Jelly filevaljellyFile=File("weather.jelly")valjellyTriples=readRdf4j(jellyFile,JELLY,None)// Print the size of the graphprintln(s"Loaded ${jellyTriples.size} triples from a Jelly file")// ---------------------------------println("\n")// By default, the parser has limits on for example the maximum size of the lookup tables.// The default supported options are [[JellyOptions.defaultSupportedOptions]].// You can change these limits by creating your own options object.valcustomOptions=JellyOptions.defaultSupportedOptions.withMaxPrefixTableSize(10)// set the maximum size of the prefix table to 10println("Trying to read the Jelly file with custom options...")try// This operation should fail because the Jelly file uses a prefix table larger than 10valcustomTriples=readRdf4j(jellyFile,JELLY,Some(customOptions))catchcasee:RdfProtoDeserializationError=>// The stream uses a prefix table size of 16, which is larger than the maximum supported size of 10.// To read this stream, set maxPrefixTableSize to at least 16 in the supportedOptions for this decoder.println(s"Failed to read the Jelly file with custom options: ${e.getMessage}")/** * Helper function to read RDF data using RDF4J's Rio library. * @param file file to read from * @param format RDF format * @param supportedOptions supported options for reading Jelly streams (optional) * @return sequence of RDF statements */privatedefreadRdf4j(file:File,format:RDFFormat,supportedOptions:Option[RdfStreamOptions]):Seq[Statement]=valparser=Rio.createParser(format)valcollector=newStatementCollector()parser.setRDFHandler(collector)supportedOptions.foreach(opt=>// If the user provided supported options, set them on the parserparser.setParserConfig(JellyParserSettings.configFromOptions(opt)))Using.resource(file.toURI.toURL.openStream()){is=>parser.parse(is)}collector.getStatements.asScala.toSeq
The RDF4J Rio writer (serializer) integration implements only the delimited variant of Jelly. It is used for writing Jelly to files on disk or sockets. Because of this, you cannot use Rio to write non-delimited Jelly data (e.g., a single message to a Kafka stream). For this, you should use the jelly-stream module or the more low-level API: Low-level usage.
However, the Rio parser (deserializer) integration will automatically detect if the parsed Jelly data is delimited or not. If it's non-delimited, the parser will assume that there is only one RdfStreamFrame in the file.
Jelly's parsers and writers are in the eu.ostrzyciel.jelly.convert.rdf4j.rio package (source code). They are automatically registered on startup using the RDFParserFactory and RDFWriterFactorySPIs provided by RDF4J.