package at.ac.univie.mminf.qskos4j.issues.conceptscheme;
import at.ac.univie.mminf.qskos4j.issues.Issue;
import at.ac.univie.mminf.qskos4j.issues.concepts.AuthoritativeConcepts;
import at.ac.univie.mminf.qskos4j.issues.labels.util.AmbiguousNotation;
import at.ac.univie.mminf.qskos4j.issues.labels.util.AmbiguousNotationMultipleResources;
import at.ac.univie.mminf.qskos4j.issues.labels.util.AmbiguousNotationWithinOneResource;
import at.ac.univie.mminf.qskos4j.result.CollectionResult;
import org.openrdf.OpenRDFException;
import org.openrdf.model.Literal;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.SKOS;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;
import java.util.*;
public class AmbiguousNotationReferences extends Issue<CollectionResult<AmbiguousNotation>> {
private AuthoritativeConcepts authoritativeConcepts;
private Map<Literal, Collection<Resource>> multiResourceConflicts;
public AmbiguousNotationReferences(AuthoritativeConcepts authoritativeConcepts) {
super(authoritativeConcepts,
"anr",
"Ambiguous Notation References",
"Finds concepts with multiple or identical notations within the same concept scheme",
IssueType.ANALYTICAL,
new URIImpl("https://github.com/cmader/qSKOS/wiki/Quality-Issues#Ambiguous_Notation_References"));
this.authoritativeConcepts = authoritativeConcepts;
}
@Override
protected CollectionResult<AmbiguousNotation> invoke() throws OpenRDFException {
multiResourceConflicts = new HashMap<>();
Set<AmbiguousNotation> ambiguousNotations = new HashSet<>();
for (Resource authConcept : authoritativeConcepts.getResult().getData()) {
ambiguousNotations.addAll(checkNotationsForConcept(authConcept));
}
for (Map.Entry<Literal, Collection<Resource>> entry : multiResourceConflicts.entrySet()) {
ambiguousNotations.add(new AmbiguousNotationMultipleResources(entry.getKey(), entry.getValue()));
}
return new CollectionResult<>(ambiguousNotations);
}
private Set<AmbiguousNotation> checkNotationsForConcept(Resource concept) throws OpenRDFException {
Set<AmbiguousNotation> ambiguousNotations = new HashSet<>();
ambiguousNotations.addAll(findAmbiguousNotationsWithinResource(concept));
findAmbiguousNotationsInMultipleResources(concept);
return ambiguousNotations;
}
private Set<AmbiguousNotation> findAmbiguousNotationsWithinResource(Resource concept) throws RepositoryException {
Set<AmbiguousNotation> ambiguousNotations = new HashSet<>();
RepositoryResult<Statement> notations = repCon.getStatements(concept, SKOS.NOTATION, null, false);
Collection<Literal> notationsForConcept = new ArrayList<>();
while (notations.hasNext()) {
Literal notationLiteral = (Literal) notations.next().getObject();
notationsForConcept.add(notationLiteral);
}
if (notationsForConcept.size() > 1) {
ambiguousNotations.add(new AmbiguousNotationWithinOneResource(concept, notationsForConcept));
}
return ambiguousNotations;
}
private void findAmbiguousNotationsInMultipleResources(Resource concept) throws OpenRDFException {
RepositoryResult<Statement> notationsForConcept = repCon.getStatements(concept, SKOS.NOTATION, null, false);
while (notationsForConcept.hasNext()) {
Literal notationLiteral = (Literal) notationsForConcept.next().getObject();
getNotationClashes(concept, notationLiteral);
}
}
private void getNotationClashes(Resource concept, Literal notationLiteral)
throws OpenRDFException
{
RepositoryResult<Statement> conceptsWithSameNotation = repCon.getStatements(null, SKOS.NOTATION, notationLiteral, false);
while (conceptsWithSameNotation.hasNext()) {
Resource conflictingResource = conceptsWithSameNotation.next().getSubject();
if (conflictingResource.equals(concept)) continue;
if (ConceptSchemeUtil.inSameConceptScheme(concept, conflictingResource, repCon) ||
ConceptSchemeUtil.inNoConceptScheme(concept, conflictingResource, repCon))
{
addToResultsMap(concept, conflictingResource, notationLiteral);
}
}
}
private void addToResultsMap(Resource resource, Resource otherResource, Literal notation) {
Collection<Resource> resources = multiResourceConflicts.get(notation);
if (resources == null) {
resources = new HashSet<>();
multiResourceConflicts.put(notation, resources);
}
resources.add(resource);
resources.add(otherResource);
}
}