Get Started

sparql-generate-jena is an implementation of SPARQL-Generate over Apache Jena. Its binaries, sources and documentation are available for download at Maven Central. To use it in your Maven project, add the following dependency declaration to your Maven project file ( *.pom file):

<dependency>
    <groupId>com.github.thesmartenergy</groupId>
    <artifactId>sparql-generate-jena</artifactId>
    <version>${sparql-generate-jena.version}</version>
</dependency>

Latest version implements iterator and custom SPARQL functions to generate RDF from JSON, XML, HTML, CSV, CBOR, plain text. See the implemented SPARQL binding functions and SPARQL-Generate iterator functions.

The javadoc contains comprehensive documentations and examples, and the sources contains a set of unit tests to get more examples.

Parsing a Query

 String queryString = "PREFIX ... GENERATE {...} FROM ... SOURCE ... ITERATOR ... WHERE {...}";
 SPARQLGenerateQuery query = (SPARQLGenerateQuery) QueryFactory.create(queryString, SPARQLGenerate.SYNTAX);

Classes PlanFactory and RootPlan

First use an instance of PlanFactory to instantiate a RootPlan for a SPARQL-Generate query.

SPARQLGenerateQuery query;
PlanFactory factory = new PlanFactory();
RootPlan plan = factory.create(query);

Then the RootPlan can be executed several times on different SPARQL datasets, and with different initial bindings (i.e., on multiple messages). Call one of the exec methods to trigger the RDF generation. Here is the signature of three of these methods:

Model exec();
void exec(Model inputModel, QuerySolution initialBindings, Model initialModel);
void exec(Dataset inputDataset, QuerySolution initialBindings, Model initialModel);

Retrieving the generated RDF

RDF generated by the execution plan is added to a Model, which is the Jena class for a RDF Graph.

  • some exec methods create a new model from scratch at execution time, fill it with the generated triples, and return it to the caller;
  • other method use parameter initialModel, and add triples.

To instantiate a Model, which is the Jena model for a RDF Graph, one may use:

ModelFactory.createDefaultModel();

Evaluating a query over a SPARQL Dataset

Part of the SPARQL GENERATE query execution consists in evaluating a SPARQL 1.1 SELECT * query over a RDF Graph, or a SPARQL Dataset. Exactly like in SPARQL 1.1. The corresponding parameters are inputModel or inputDataset. To instantiate a Dataset, which is the Jena class for a SPARQL Dataset, one may use:

DatasetFactory.create(Model model);

Note:

  • If initialModel == null, then an IllegalArgumentException exception will be thrown;
  • The behaviour when the same instance is passed as inputModel and initialModel is not specified. You should avoid this situation.

Generating RDF for streams of messages

Finally, one may execute the query with initial bindings. This is useful when one wants to apply the same plan to generate RDF from multiple messages regularly received from a lightweight sensor for instance.

Suppose one needs to execute a plan with a variable ?msg bound to a message with textual representation "mymessage" and internet media-type application/json. Then the RDF literal to bind to ?msg:

  • has lexical form "mymessage",
  • has datatype IRI <http://www.iana.org/assignments/media-types/application/json> (this is optional).

In SPARQL Generate over Apache Jena, one calls an exec method with parameter initialBindings. The following code shows how this can be done with the plan instantiated above:

String variable = "msg";
String message = "mymessage";
String uri = "http://www.iana.org/assignments/media-types/application/json";

RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(uri);
Node arqLiteral = NodeFactory.createLiteral(message, dt);
RDFNode jenaLiteral = initialModel.asRDFNode(arqLiteral);

QuerySolutionMap initialBinding = new QuerySolutionMap();
initialBinding.add(variable, jenaLiteral);

Model initialModel = ModelFactory.createDefaultModel();

plan.exec(initialBinding, initialModel);

Using a File Manager

The default behaviour of the implementation is to attempt to operate a HTTP GET request to the URI of a source, and to use the retrieved document as the literal for this name. One may choose to use local files instead.

The Jena FileManager is designed just for that. It uses a configuration file to load files from disk instead of attempting HTTP GET calls. See The Jena FileManager and LocationMapper. The following code illustrates how a FileManager can be passed to the constructor of a PlanFactory, in order to be used during the execution of the plans this PlanFactory will create.

Model conf = RDFDataMgr.loadModel("file:/path/to/configuration.ttl");
LocationMapper mapper = new LocationMapper(conf);
FileManager fm = new FileManager();

fm.setLocationMapper(mapper);

Locator loc;

loc = new LocatorFile("file:/path/to/directory1");
fm.addLocator(loc);

loc = new LocatorFile("file:/path/to/directory2");
fm.addLocator(loc);

PlanFactory factory = new PlanFactory(fm);
...