I'm looking at implementing a property function that matches when its
subject and object are the same blank node. This seemed like a
trivial case for subclassing the assign property function that's
included with Jena. Here's a relatively minimal example that creates
such a property function and uses it in a SPARQL query (also available
as a Gist, https://gist.github.com/tayloj/349dd97014121a6c710c). I
can see that the property function is getting called based on the
query output and on the logger output. However, if I change the
property usage to be a property path, e.g., just by adding a * to it,
i.e., changing
" ?s <java:CBDSPARQLExample$sameBlank> ?t .\n" +
to
" ?s <java:CBDSPARQLExample$sameBlank>* ?t .\n" +
I get no log output whatsoever, which indicates that the property
function isn't getting called, and of course that means I get rather
different results, too. Are property functions supposed to be invoked
in property paths?
Thanks in advance,
//JT
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.sparql.engine.ExecutionContext;
import com.hp.hpl.jena.sparql.engine.QueryIterator;
import com.hp.hpl.jena.sparql.engine.binding.Binding;
import com.hp.hpl.jena.sparql.pfunction.library.assign;
import com.hp.hpl.jena.sparql.util.IterLib;
public class CBDSPARQLExample {
private final static Logger LOGGER = LoggerFactory.getLogger(
CBDSPARQLExample.class );
public static class sameBlank extends assign {
@Override
public QueryIterator execEvaluated( Binding binding, Node subject,
Node predicate, Node object, ExecutionContext execCxt) {
LOGGER.info( "called with {} {} {}", new Object[] { subject,
predicate , object } );
if ( subject.isBlank() || object.isBlank() ) {
return super.execEvaluated(binding, subject, predicate,
object, execCxt);
}
else {
return IterLib.noResults(execCxt);
}
}
}
private final static String MODEL_CONTENT = "" +
"@prefix : <urn:ex:>\n" +
"\n" +
":A :p :B ;\n" +
" :q [ :r :C, :D ; :s [ :t :U ] ] .\n" +
":C :p :E .\n" +
":D :q :F .\n";
private final static String CBD_QUERY = "" +
"prefix : <urn:ex:>\n" +
"prefix fns: <http://example.org/fns#>" +
"\n" +
"construct { ?t ?p ?o }\n" +
"where {\n" +
" ?s ?p ?o .\n" +
" ?s <java:CBDSPARQLExample$sameBlank> ?t .\n" +
"}\n" +
"";
public static void main(String[] args) throws IOException {
final Model model = ModelFactory.createDefaultModel();
try ( final InputStream in = new ByteArrayInputStream(
MODEL_CONTENT.getBytes() )) {
model.read( in, null, "TTL" );
}
QueryExecution exec = QueryExecutionFactory.create( CBD_QUERY, model );
final Model cbd = exec.execConstruct();
cbd.write( System.out, "TTL" );
}
}
--
Joshua Taylor, http://www.cs.rpi.edu/~tayloj/