package at.ac.univie.mminf.qskos4j.issues.labels; import at.ac.univie.mminf.qskos4j.issues.Issue; import at.ac.univie.mminf.qskos4j.issues.labels.util.LabelConflict; import at.ac.univie.mminf.qskos4j.issues.labels.util.LabeledConcept; import at.ac.univie.mminf.qskos4j.issues.labels.util.ResourceLabelsCollector; import at.ac.univie.mminf.qskos4j.issues.labels.util.LabelConflictsResult; import org.openrdf.OpenRDFException; import org.openrdf.model.Literal; import org.openrdf.model.impl.URIImpl; import org.openrdf.repository.RepositoryConnection; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; /** * Finds concepts having identical entries for prefLabel, altLabel or hiddenLabel ( * <a href="https://github.com/cmader/qSKOS/wiki/Quality-Issues#wiki-Disjoint_Labels_Violation">Disjoint Labels Violation</a> * ). */ public class DisjointLabelsViolations extends Issue<LabelConflictsResult> { private Map<Literal, LabelConflict> nonDisjointLabels; private ResourceLabelsCollector resourceLabelsCollector; public DisjointLabelsViolations(ResourceLabelsCollector resourceLabelsCollector) { super("dlv", "Disjoint Labels Violation", "Finds resources with identical entries for different label types", IssueType.ANALYTICAL, new URIImpl("https://github.com/cmader/qSKOS/wiki/Quality-Issues#disjoint-labels-violation")); this.resourceLabelsCollector = resourceLabelsCollector; } @Override protected LabelConflictsResult invoke() throws OpenRDFException { findNonDisjointLabels(); return new LabelConflictsResult(nonDisjointLabels.values()); } private void findNonDisjointLabels() throws OpenRDFException { Map<Literal, Collection<LabeledConcept>> resourcesByLabel = orderResourcesByLabel(); extractNonDisjointConflicts(resourcesByLabel); } private Map<Literal, Collection<LabeledConcept>> orderResourcesByLabel() throws OpenRDFException { Map<Literal, Collection<LabeledConcept>> resourcesByLabel = new HashMap<Literal, Collection<LabeledConcept>>(); for (LabeledConcept labeledResource : resourceLabelsCollector.getLabeledConcepts()) { Literal literal = labeledResource.getLiteral(); Collection<LabeledConcept> resourcesForLiteral = resourcesByLabel.get(literal); if (resourcesForLiteral == null) { resourcesForLiteral = new HashSet<LabeledConcept>(); resourcesByLabel.put(literal, resourcesForLiteral); } resourcesForLiteral.add(labeledResource); } return resourcesByLabel; } private void extractNonDisjointConflicts(Map<Literal, Collection<LabeledConcept>> resourcesByLabel) { nonDisjointLabels = new HashMap<Literal, LabelConflict>(); for (Map.Entry<Literal, Collection<LabeledConcept>> entry : resourcesByLabel.entrySet()) { LabelConflict labelConflict = findNonDisjointConflict(entry.getValue()); if (labelConflict != null) { nonDisjointLabels.put(entry.getKey(), labelConflict); } } } private LabelConflict findNonDisjointConflict(Collection<LabeledConcept> identicallyLabeledResources) { LabelConflict labelConflict = null; for (LabeledConcept labeledResource : identicallyLabeledResources) { for (LabeledConcept otherLabeledResource : identicallyLabeledResources) { if (hasNonDisjointConflict(labeledResource, otherLabeledResource)) { if (labelConflict == null) labelConflict = new LabelConflict(); labelConflict.add(labeledResource); labelConflict.add(otherLabeledResource); } } } return labelConflict; } private boolean hasNonDisjointConflict(LabeledConcept resource1, LabeledConcept resource2) { return (resource1.getConcept() == resource2.getConcept()) && (resource1.getLabelType() != resource2.getLabelType()); } @Override public void setRepositoryConnection(RepositoryConnection repCon) { resourceLabelsCollector.setRepositoryConnection(repCon); super.setRepositoryConnection(repCon); } }