0

I’m using the Jena query builder from the Jena-extras and I was wondering if there was a way to add a SERVICE clause to a SelectBuilder object.

My code right now looks like this:

SelectBuilder builder = new SelectBuilder()
        .addPrefix( "rdf",  "http://www.w3.org/1999/02/22-rdf-syntax-ns#" )
        .addPrefix("dbo", "http://dbpedia.org/ontology/")
        .addVar("?uri")
        .addWhere("?uri", "rdf:type", "dbo:Company")
        .setLimit(100);

Query query = builder.build();
System.out.println(query);

which outputs this:

PREFIX  dbo:  <http://dbpedia.org/ontology/>
PREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT  ?uri
WHERE
  { ?uri  rdf:type  dbo:Company}
LIMIT   100

I’ve also tried adding the SERVICE clause to a Query object after calling builder.build(), but it seems like it’s only possible through the ARQ API using body.addElement(new ElementService("http://any.domain/sparql", elementBlock)). The problem is that you can’t get the elementBlock from a Query object or SelectBuilder object.

Is there a way to add a SERVICE clause using the query builder or are there known workarounds without resorting to the verbose ARQ API, or should I try and extend the SelectBuilder API myself?

jDeJong
  • 9
  • 3
  • and yes, looks like `SERVICE` is missing in SelectBuilder. You could open a feature request or even better contribute, extend the code and make a pull request. Contributions are always welcome I think. – UninformedUser Jun 23 '21 at 16:18
  • "you can’t get the elementBlock from a Query object" - well ... jena.apache.org/documentation/javadoc/arq/org/apache/jena/query/… or did you mean something else? I mean, to get the `elementBlock` variable for the argument, you could simply create another query that covers the part of the `SERVICE` clause, and then get the element pattern from this which you put into the `ElementService` constructor – UninformedUser Jun 23 '21 at 16:20
  • Contributions are always welcome. – AndyS Jun 23 '21 at 18:54
  • @UninformedUser Yes, you can get by calling `query.getQueryPattern()`. I wasn't yet aware of some of the interchangeability of Element and ElementBlock etc. – jDeJong Jun 28 '21 at 14:20
  • @AndyS Thanks for the help, and maybe I'll submit a PR some time, but I'd have to look into the query builder a little more in order to get it right. – jDeJong Jun 28 '21 at 14:22

1 Answers1

0

For anyone having the same problem, I asked the devs who gave me a useful hint (thank you, Andy Seaborne), and the solution seems to be as follows:

SelectBuilder builder = new SelectBuilder()
        .addPrefix( "rdf",  "http://www.w3.org/1999/02/22-rdf-syntax-ns#" )
        .addPrefix("dbo", "http://dbpedia.org/ontology/")
        .addVar("?uri")
        .addWhere("?uri", "rdf:type", "dbo:Company")
        .setLimit(100);

Query query = builder.build();
ElementGroup body = new ElementGroup();
body.addElement(new ElementService("http://dbpedia.org/sparql", query.getQueryPattern()));
query.setQueryPattern(body);

System.out.println(query);

This code outputs the following query:

PREFIX  dbo:  <http://dbpedia.org/ontology/>
PREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT  ?uri
WHERE
  { SERVICE <http://dbpedia.org/sparql>
      { ?uri  rdf:type  dbo:Company}
  }
LIMIT   100

Too bad that this isn't a part of the query builder's fluent API out of the box, but any savvy Java engineer can write an extension or helper for this.

jDeJong
  • 9
  • 3