On 16/08/2020 10:09, Dimitris Spanos wrote:
Hi Andy,

Thank you for the extremely useful information.

Indeed, I want to pass the default graph and named graph URIs to MyQueryEngine, 
so I went for your advice and extended SPARQLQueryProcessor accordingly to 
store this information in the context of MyDatasetGraph.

I could have retrieved the same information from DynamicDatasetGraph (via 
getWrapped() as you said), but I think the current solution leads to cleaner 
code.

Conveniently, in my Jena subsystem "init" class, I also registered the above 
handler to the Query operation with FusekiExt.registerOperation(), avoiding any changes 
to Fuseki Core or configuring/starting the server programmatically.

I had completely forgotten about FusekiExt!

    Andy


Cheers,
Dimitris

On 2020/08/15 13:08:21, Andy Seaborne <[email protected]> wrote:


On 15/08/2020 11:59, Dimitris Spanos wrote:
Hi all,

I am trying to implement a custom QueryEngine that would handle query
optimization and evaluation for a custom Dataset implementation, as
mentioned in the documentation (
https://jena.apache.org/documentation/query/arq-query-eval.html#custom-query-engines
).

Following the lines in the example in
src-examples/arq.examples.engine.MyQueryEngine, I implemented a similar
MyQueryEngine and MyQueryEngineFactory, with the accept() implementation
looking like the following:

public boolean accept(Query query, DatasetGraph dataset, Context context) {
    return dataset instanceof MyDatasetGraph;
}

where MyDatasetGraph is a DatasetGraph implementation, backing the
custom Dataset implementation, for which I want to use MyQueryEngine.

While this works fine for a simple query without any FROM/FROM NAMED
clause, the above accept() method does not work anymore when the query
includes a dataset specification in a FROM/FROM NAMED clause.

Just to check - what effect are you looking for by using FROM/FROM
NAMED? just passthru to the query engine?

This happens because in the query processing phase occurring in
SPARQL_QueryDataset, MyDatasetGraph gets wrapped in a
DynamicDatasetGraph, which does not seem to have any public methods to
get the wrapped graph.

You can add your own query processor if the provided one does not suit
your needs.

Override "decideDataset" to return as if no FROM/FROM NAMED were present.

org.apache.jena.fuseki.main.examples.ExtendFuseki_AddService_1

(for Fuseki main but the mechanism underneath is part of core Fuseki -
find the operation registry registry and add your own.)

(Or replace the standard registration - that will then work with
dispatch by content-type - there can be only one process for each
content type. It is also how dispatch on "/dataset?query" (no service
name) works - again, there can be only one processor for "?query" at an
endpoint.)


Q1: Is there a way to determine whether a DynamicDatasetGraph wraps an
instance of MyDatasetGraph? If not, could I somehow use Context to
determine the type of Dataset/DatasetGraph being queried?

public static class DynamicDatasetGraph
      extends DatasetGraphReadOnly
      implements DatasetGraphWrapperView

DatasetGraphReadOnly extends DatasetGraphWrapper

This should work:

DatasetGraphWrapper.getWrapped()

Q2: I noticed that this behaviour occurs only in SPARQL_QueryDataset, which
is the default ActionService for the "query" Operation in Fuseki. It could
be that using SPARQL_QueryGeneral for the Query operation might solve the
problem for me, but can this be configured in Fuseki configuration? I could
not find anything relevant in
https://jena.apache.org/documentation/fuseki2/fuseki-config-endpoint.html.

SPARQL_QueryGeneral is a standalone servlet to go with an HTML form and
there is no dataset behind it.

e.g. http://www.sparql.org/sparql.html

The form has to provide the data - e.g. a query with VALUES clause - a
FROM would load from the web.

It can't be graph from the dataset because there isn't one (well, there
is a fake immutable empty one)

Q3: By digging some more, I saw that SPARQL_QueryGeneral is registered as
an ActionService for the "query" operation when Fuseki starts with either
of the --sparqler or --general arguments. Nevertheless, I should mention
that I have a strong preference in starting Fuseki as a WAR with just a
configuration template for my new dataset type. Can I pass command line
arguments or even start Fuseki programmatically while still running it as a
Web Application?

If you mean so it can be dropped into a web container? You an start
Fuseki (main) inside an application that is inside a WAR file.  Depeding
on webapp container, ports may be complicated.

jena-fuseki-war is a drop in WAR file.

jena-fuseki-full jar is Fuseki packaged with Jetty and is a web application.

jena-fuseki-server is a combined, but non-war version.



Thanks in advance,
Dimitris


Reply via email to