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/

Reply via email to