Created
January 14, 2011 11:35
-
-
Save shellac/779502 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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