package at.ac.univie.mminf.qskos4j.issues.relations; import at.ac.univie.mminf.qskos4j.issues.Issue; import at.ac.univie.mminf.qskos4j.result.CollectionResult; import at.ac.univie.mminf.qskos4j.util.Tuple; import at.ac.univie.mminf.qskos4j.util.vocab.SparqlPrefix; import org.openrdf.OpenRDFException; import org.openrdf.model.Resource; import org.openrdf.model.Statement; import org.openrdf.model.URI; import org.openrdf.model.Value; import org.openrdf.model.impl.StatementImpl; import org.openrdf.model.impl.URIImpl; import org.openrdf.query.*; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; /** * Finds <a href="https://github.com/cmader/qSKOS/wiki/Quality-Issues#wiki-Solely_Transitively_Related_Concepts">Solely Transitively Related Concepts</a>. */ public class SolelyTransitivelyRelatedConcepts extends Issue<CollectionResult<Tuple<Resource>>> { private String[][] transitiveNontransiviteInverseProperties = { {"skos:broaderTransitive", "skos:broader", "skos:narrower"}, {"skos:narrowerTransitive", "skos:narrower", "skos:broader"}}; private Collection<Statement> solitaryTransitiveRelations; public SolelyTransitivelyRelatedConcepts() { super("strc", "Solely Transitively Related Concepts", "Concepts only related by skos:broaderTransitive or skos:narrowerTransitive", IssueType.ANALYTICAL, new URIImpl("https://github.com/cmader/qSKOS/wiki/Quality-Issues#solely-transitively-related-concepts") ); } @Override protected CollectionResult<Tuple<Resource>> invoke() throws OpenRDFException { solitaryTransitiveRelations = new ArrayList<>(); for (String[] transitivePropertyPair : transitiveNontransiviteInverseProperties) { String query = createSolitaryTransitiveRelationsQuery(transitivePropertyPair); TupleQuery tupleQuery = repCon.prepareTupleQuery(QueryLanguage.SPARQL, query); addToResults(tupleQuery.evaluate(), transitivePropertyPair[0]); } return createReport(); } private CollectionResult<Tuple<Resource>> createReport() { Collection<Tuple<Resource>> relatedConcepts = new HashSet<>(); for (Statement statement : solitaryTransitiveRelations) { relatedConcepts.add(new Tuple<>(statement.getSubject(), (Resource) statement.getObject())); } return new CollectionResult(relatedConcepts); } private String createSolitaryTransitiveRelationsQuery( String[] transitiveNontransiviteInverseProperties) { return SparqlPrefix.SKOS +" "+ SparqlPrefix.RDFS + "SELECT DISTINCT ?resource1 ?resource2 "+ "WHERE {" + "?resource1 " +transitiveNontransiviteInverseProperties[0]+ " ?resource2 . "+ "FILTER NOT EXISTS {?resource1 ("+transitiveNontransiviteInverseProperties[1]+ "|^"+transitiveNontransiviteInverseProperties[2]+")* ?resource2}" + "}"; } private void addToResults(TupleQueryResult result, String solitaryRelation) throws QueryEvaluationException { while (result.hasNext()) { BindingSet queryResult = result.next(); Resource resource1 = (Resource) queryResult.getValue("resource1"); Value resource2 = queryResult.getValue("resource2"); URI relation = new URIImpl(solitaryRelation.replace("skos:", SparqlPrefix.SKOS.getNameSpace())); solitaryTransitiveRelations.add(new StatementImpl(resource1, relation, resource2)); } } }