Skip to content

Commit

Permalink
[Enhancement #85] Load inferred broader terms when necessary.
Browse files Browse the repository at this point in the history
  • Loading branch information
ledsoft committed May 4, 2021
1 parent b67c81d commit ef76a44
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 7 deletions.
54 changes: 47 additions & 7 deletions src/main/java/cz/cvut/kbss/termit/persistence/dao/TermDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,15 @@ private <T extends AbstractTerm> List<T> findAllFrom(Set<URI> contexts, Pageable
final Descriptor descriptor = descriptorFactory.termDescriptor((URI) null);
resolveWorkspaceAndCanonicalContexts().forEach(descriptor::addContext);
query.setDescriptor(descriptor);
return executeQueryAndLoadSubTerms(query, contexts);
final List<T> result = executeQueryAndLoadSubTerms(query, contexts);
if (TermDto.class.isAssignableFrom(resultType)) {
result.forEach(t -> {
final TermDto dto = (TermDto) t;
initParentTerms(dto);
dto.getParentTerms().addAll(loadInferredParentTerms(dto, contexts, dto.getParentTerms()));
});
}
return result;
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
Expand Down Expand Up @@ -409,12 +417,39 @@ private List<TermDto> findAllFrom(Set<URI> contexts, String searchString, Pageab
final Descriptor descriptor = descriptorFactory.termDescriptor((URI) null);
contexts.forEach(descriptor::addContext);
query.setDescriptor(descriptor);
return executeQueryAndLoadSubTerms(query, contexts);
final List<TermDto> result = executeQueryAndLoadSubTerms(query, contexts);
result.forEach(t -> {
initParentTerms(t);
t.getParentTerms().addAll(loadInferredParentTerms(t, contexts, t.getParentTerms()));
});
return result;
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
}

private void initParentTerms(TermDto t) {
if (t.getParentTerms() == null) {
t.setParentTerms(new LinkedHashSet<>());
}
}

private List<TermDto> loadInferredParentTerms(TermDto term, Set<URI> graphs, Set<TermDto> exclude) {
return em.createNativeQuery("SELECT DISTINCT ?parent WHERE {" +
"GRAPH ?g { " +
"?parent a ?type ." +
"}" +
"?term ?broader ?parent ." + // Let broader be outside of the graph to include inference
"FILTER (?g IN (?graphs))" +
"FILTER (?parent NOT IN (?exclude))" +
"}", TermDto.class).setParameter("type", typeUri)
.setParameter("term", term)
.setParameter("broader", URI.create(SKOS.BROADER))
.setParameter("graphs", graphs)
.setParameter("exclude", exclude)
.getResultList();
}

/**
* Returns true if the vocabulary does not contain any terms.
*
Expand Down Expand Up @@ -463,12 +498,13 @@ private void loadAdditionTermMetadata(AbstractTerm term, Set<URI> graphs) {
*/
private Set<TermInfo> loadSubTermInfo(AbstractTerm parent, Set<URI> graphs) {
final Stream<TermInfo> subTermsStream = em.createNativeQuery("SELECT ?entity ?label ?vocabulary WHERE {" +
"GRAPH ?g { ?entity ?broader ?parent ;" +
"a ?type ;" +
"GRAPH ?g { " +
"?entity a ?type ;" +
"?hasLabel ?label ." +
"FILTER (lang(?label) = ?labelLang) ." +
"}" +
"?entity ?inVocabulary ?vocabulary ." +
"?entity ?broader ?parent ; " + // Let broader be outside of the graph to allow including inferences
"?inVocabulary ?vocabulary ." +
"FILTER (?g in (?graphs))" +
"} ORDER BY LCASE(?label)", "TermInfo")
.setParameter("type", typeUri)
Expand Down Expand Up @@ -582,7 +618,11 @@ private List<TermDto> findAllImpl(String searchString, URI vocabularyIri) {
.setParameter("searchString", searchString, config.get(ConfigParam.LANGUAGE));
query.setDescriptor(descriptorFactory.termDescriptor(vocabularyIri));
final List<TermDto> terms = executeQueryAndLoadSubTerms(query, Collections.singleton(vocabularyCtx));
terms.forEach(t -> loadParentSubTerms(t, vocabularyCtx));
terms.forEach(t -> {
loadParentSubTerms(t, vocabularyCtx);
initParentTerms(t);
t.getParentTerms().addAll(loadInferredParentTerms(t, Collections.singleton(vocabularyCtx), t.getParentTerms()));
});
return terms;
} catch (RuntimeException e) {
throw new PersistenceException(e);
Expand Down Expand Up @@ -643,7 +683,7 @@ public List<Term> findAllSubTerms(Term parent) {
"GRAPH ?g { " +
"?term a ?type ." +
"}" +
"?term ?broader ?parent ." +
"?term ?broader ?parent ." + // Let broader be outside of the graph to include inference
"FILTER (?g in (?graphs))" +
"}", Term.class).setParameter("type", typeUri)
.setParameter("broader", URI.create(SKOS.BROADER))
Expand Down
29 changes: 29 additions & 0 deletions src/test/java/cz/cvut/kbss/termit/persistence/dao/TermDaoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -727,4 +727,33 @@ void subTermLoadingSortsThemByLabel() {
assertEquals(child.getUri(), next.getUri());
}
}

@Test
void findAllBySearchStringAndVocabularyLoadsInferredParentTerms() {
final Term term = Generator.generateTermWithId(vocabulary.getUri());
final String searchString = "test";
term.getLabel().set(Constants.DEFAULT_LANGUAGE, searchString + " value");
final Term parent = Generator.generateTermWithId(vocabulary.getUri());
vocabulary.getGlossary().addRootTerm(parent);
transactional(() -> {
em.persist(term, descriptorFactory.termDescriptor(vocabulary));
em.persist(parent, descriptorFactory.termDescriptor(vocabulary));
em.merge(vocabulary.getGlossary(), descriptorFactory.glossaryDescriptor(vocabulary));
addTermInVocabularyRelationship(term, vocabulary.getUri());
addTermInVocabularyRelationship(parent, vocabulary.getUri());
insertInferredBroaderRelationship(term, parent, em);
});

final List<TermDto> result = sut.findAll(searchString, vocabulary);
assertEquals(1, result.size());
assertThat(result.get(0).getParentTerms(), hasItem(new TermDto(parent)));
}

static void insertInferredBroaderRelationship(Term child, Term parent, EntityManager em) {
final Repository repo = em.unwrap(Repository.class);
try (final RepositoryConnection conn = repo.getConnection()) {
final ValueFactory vf = conn.getValueFactory();
conn.add(vf.createIRI(child.getUri().toString()), vf.createIRI(SKOS.BROADER), vf.createIRI(parent.getUri().toString()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -868,4 +868,53 @@ void updateSupportsTermWithSupertypeInCanonicalContainer() {
assertEquals(term, result);
assertThat(result.getSuperTypes(), hasItem(superType));
}

@Test
void findAllInCurrentWorkspaceBySearchStringLoadsInferredParentTerms() {
final String searchString = "search";
final Term term = Generator.generateTermWithId();
final Term parent = Generator.generateTermWithId();
term.getLabel().set(Constants.DEFAULT_LANGUAGE, searchString + " string label");
term.setGlossary(vocabulary.getGlossary().getUri());
final Vocabulary anotherVocabularyInWs = Generator.generateVocabularyWithId();
saveVocabulary(anotherVocabularyInWs);
parent.setGlossary(anotherVocabularyInWs.getGlossary().getUri());
transactional(() -> {
em.persist(term, new EntityDescriptor(vocabulary.getUri()));
vocabulary.getGlossary().addRootTerm(term);
em.merge(vocabulary.getGlossary(), descriptorFactory.glossaryDescriptor(vocabulary));
Generator.addTermInVocabularyRelationship(term, vocabulary.getUri(), em);
em.persist(parent, new EntityDescriptor(anotherVocabularyInWs.getUri()));
Generator.addTermInVocabularyRelationship(parent, anotherVocabularyInWs.getUri(), em);
TermDaoTest.insertInferredBroaderRelationship(term, parent, em);
});

final List<TermDto> result = sut.findAll(searchString);
assertEquals(1, result.size());
assertThat(result.get(0).getParentTerms(), hasItem(new TermDto(parent)));
}

@Test
void findAllByPageableLoadsInferredParentTerms() {
final Term term = Generator.generateTermWithId();
final Term parent = Generator.generateTermWithId();
term.setGlossary(vocabulary.getGlossary().getUri());
final Vocabulary anotherVocabularyInWs = Generator.generateVocabularyWithId();
saveVocabulary(anotherVocabularyInWs);
parent.setGlossary(anotherVocabularyInWs.getGlossary().getUri());
transactional(() -> {
em.persist(term, new EntityDescriptor(vocabulary.getUri()));
vocabulary.getGlossary().addRootTerm(term);
em.merge(vocabulary.getGlossary(), descriptorFactory.glossaryDescriptor(vocabulary));
Generator.addTermInVocabularyRelationship(term, vocabulary.getUri(), em);
em.persist(parent, new EntityDescriptor(anotherVocabularyInWs.getUri()));
Generator.addTermInVocabularyRelationship(parent, anotherVocabularyInWs.getUri(), em);
TermDaoTest.insertInferredBroaderRelationship(term, parent, em);
});

final List<TermDto> results = sut.findAll(Constants.DEFAULT_PAGE_SPEC);
final Optional<TermDto> res = results.stream().filter(t -> t.getUri().equals(term.getUri())).findFirst();
assertTrue(res.isPresent());
assertThat(res.get().getParentTerms(), hasItem(new TermDto(parent)));
}
}

0 comments on commit ef76a44

Please sign in to comment.