package at.ac.univie.mminf.qskos4j.issues;
import at.ac.univie.mminf.qskos4j.util.graph.NamedEdge;
import at.ac.univie.mminf.qskos4j.util.vocab.SparqlPrefix;
import org.jgrapht.DirectedGraph;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.openrdf.OpenRDFException;
import org.openrdf.model.Resource;
import org.openrdf.model.Value;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.RepositoryConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HierarchyGraphBuilder {
private final Logger logger = LoggerFactory.getLogger(HierarchyGraphBuilder.class);
private DirectedGraph<Resource, NamedEdge> graph;
private RepositoryConnection repCon;
public DirectedGraph<Resource, NamedEdge> createGraph() throws OpenRDFException
{
if (graph == null) {
logger.info("Creating hierarchy graph");
graph = new DefaultDirectedGraph<>(NamedEdge.class);
addResultsToGraph(findTriples("skos:broaderTransitive"), false);
addResultsToGraph(findTriples("skos:narrowerTransitive"), true);
}
return graph;
}
private TupleQueryResult findTriples(String skosHierarchyProperty) throws OpenRDFException
{
String query = createHierarchicalGraphQuery(skosHierarchyProperty);
return repCon.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
}
private String createHierarchicalGraphQuery(String skosHierarchyProperty) {
return SparqlPrefix.SKOS +" "+ SparqlPrefix.RDFS +
"SELECT DISTINCT ?resource ?otherResource "+
"WHERE {" +
"?resource " +skosHierarchyProperty+ " ?otherResource ."+
"}";
}
private void addResultsToGraph(TupleQueryResult result, boolean invertEdges)
throws QueryEvaluationException
{
while (result.hasNext()) {
BindingSet bindingSet = result.next();
addToGraph(
bindingSet.getValue("resource"),
bindingSet.getValue("otherResource"),
invertEdges);
}
}
private void addToGraph(
Value resource,
Value otherResource,
boolean invertEdges)
{
Resource resourceNode = (Resource) resource;
graph.addVertex(resourceNode);
Resource otherNode = (Resource) otherResource;
graph.addVertex(otherNode);
if (invertEdges) {
graph.addEdge(otherNode, resourceNode, new NamedEdge());
}
else {
graph.addEdge(resourceNode, otherNode, new NamedEdge());
}
}
public void setRepositoryConnection(RepositoryConnection repCon) {
this.repCon = repCon;
graph = null;
}
}