Skip to content

Instantly share code, notes, and snippets.

@shellac
Created January 14, 2011 11:35
Show Gist options
  • Save shellac/779502 to your computer and use it in GitHub Desktop.
Save shellac/779502 to your computer and use it in GitHub Desktop.
package org.ilrt.researchrevealed.describehandler;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.rdf.model.impl.StmtIteratorImpl;
import com.hp.hpl.jena.sparql.ARQConstants;
import com.hp.hpl.jena.sparql.core.Quad;
import com.hp.hpl.jena.sparql.core.describe.DescribeHandler;
import com.hp.hpl.jena.sparql.core.describe.DescribeHandlerFactory;
import com.hp.hpl.jena.sparql.core.describe.DescribeHandlerRegistry;
import com.hp.hpl.jena.sparql.util.Context;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.util.iterator.Filter;
import com.hp.hpl.jena.vocabulary.RDFS;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Damian Steer <[email protected]>
*/
public class BackwardForwardDescribeFactory implements DescribeHandlerFactory {
final static Logger log = LoggerFactory.getLogger(BackwardForwardDescribeFactory.class);
static {
log.info("Attaching replacement describe handler");
DescribeHandlerRegistry reg = DescribeHandlerRegistry.get();
log.info("Clearing existing describe handlers");
reg.clear();
reg.add(new BackwardForwardDescribeFactory());
log.info("Attached");
}
@Override
public DescribeHandler create() {
return new BackwardForwardDescribe();
}
public static class BackwardForwardDescribe implements DescribeHandler {
private Dataset dataset;
private Model result;
private Model defaultModel;
private Model unionModel;
private Filter<Statement> filter;
private final int limit;
private final String ns;
public BackwardForwardDescribe() {
this(2000, "http://vocab.bris.ac.uk/rr/closed#");
}
public BackwardForwardDescribe(int limit, String ns) {
this.limit = limit;
this.ns = ns;
}
@Override
public void start(Model accumulateResultModel, Context qContext) {
this.result = accumulateResultModel;
this.dataset = (Dataset) qContext.get(ARQConstants.sysCurrentDataset);
this.defaultModel = dataset.getDefaultModel();
this.unionModel = dataset.getNamedModel(Quad.unionGraph.getURI());
this.filter = new CountAndNSFilter(limit, ns);
}
@Override
public void describe(Resource resource) {
result.add(toSI(defaultModel.listStatements(resource, null, (RDFNode) null).filterKeep(filter)));
result.add(toSI(defaultModel.listStatements(null, null, resource).filterKeep(filter)));
result.add(toSI(unionModel.listStatements(resource, null, (RDFNode) null).filterKeep(filter)));
result.add(toSI(unionModel.listStatements(null, null, resource).filterKeep(filter)));
// Gather labels for dangling refs
Model labels = ModelFactory.createDefaultModel();
ExtendedIterator<RDFNode> it = result.listObjects().andThen(result.listSubjects());
while (it.hasNext()) {
RDFNode node = it.next();
if (node.isLiteral() || resource.equals(node)) continue;
labels.add(defaultModel.listStatements((Resource) node, RDFS.label, (RDFNode) null));
labels.add(unionModel.listStatements((Resource) node, RDFS.label, (RDFNode) null));
}
result.add(labels);
}
@Override
public void finish() {
}
}
/**
* Utility method that really shouldn't need to exist
* @param it
* @return
*/
static StmtIterator toSI(final Iterator<Statement> it) {
return new StmtIteratorImpl(it);
}
/**
*
*/
static class CountAndNSFilter extends Filter<Statement> {
private final int limit;
private final String prefix;
private int count;
public CountAndNSFilter(final int limit, final String prefix) {
this.limit = limit;
this.prefix = prefix;
this.count = 0;
}
@Override
public boolean accept(Statement o) {
if (o.getPredicate().equals(RDFS.label)) return true; // We ignore labels
if ((prefix != null) && o.getPredicate().getURI().startsWith(prefix)) return false;
if (count >= limit) return false;
count++;
if (count == limit) log.warn("Safety limit hit describing resource");
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment