Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement kbss-cvut/termit-ui#479] Allow viewing terms without label in primary language #281

Merged
merged 2 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/main/java/cz/cvut/kbss/termit/persistence/dao/TermDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ public List<TermDto> findAllIncludingImported(Vocabulary vocabulary) {

/**
* Loads a page of root terms (terms without a parent) contained in the specified vocabulary.
* <p>
* Terms with a label in the instance language are prepended.
*
* @param vocabulary Vocabulary whose root terms should be returned
* @param pageSpec Page specification
Expand All @@ -401,13 +403,14 @@ public List<TermDto> findAllRoots(Vocabulary vocabulary, Pageable pageSpec, Coll
Objects.requireNonNull(vocabulary);
Objects.requireNonNull(pageSpec);
TypedQuery<TermDto> query = em.createNativeQuery("SELECT DISTINCT ?term WHERE {" +
"SELECT DISTINCT ?term ?hasLocaleLabel WHERE {" +
"GRAPH ?context { " +
"?term a ?type ;" +
"?hasLabel ?label ." +
"?vocabulary ?hasGlossary/?hasTerm ?term ." +
"FILTER (lang(?label) = ?labelLang) ." +
"BIND((lang(?label) = ?labelLang) as ?hasLocaleLabel) ." +
"FILTER (?term NOT IN (?included))" +
"}} ORDER BY " + orderSentence("?label"),
"}} ORDER BY DESC(?hasLocaleLabel) lang(?label) " + orderSentence("?label") + "}",
TermDto.class);
query = setCommonFindAllRootsQueryParams(query, false);
try {
Expand Down Expand Up @@ -453,6 +456,8 @@ private static String r(String string, String from, String to) {

/**
* Loads a page of root terms (terms without a parent).
* <p>
* Terms with a label in the instance language are prepended.
*
* @param pageSpec Page specification
* @param includeTerms Identifiers of terms which should be a part of the result. Optional
Expand All @@ -462,13 +467,14 @@ private static String r(String string, String from, String to) {
public List<TermDto> findAllRoots(Pageable pageSpec, Collection<URI> includeTerms) {
Objects.requireNonNull(pageSpec);
TypedQuery<TermDto> query = em.createNativeQuery("SELECT DISTINCT ?term WHERE {" +
"SELECT DISTINCT ?term ?hasLocaleLabel WHERE {" +
"?term a ?type ; " +
"?hasLabel ?label . " +
"?vocabulary ?hasGlossary/?hasTerm ?term . " +
"FILTER (lang(?label) = ?labelLang) . " +
"BIND((lang(?label) = ?labelLang) as ?hasLocaleLabel) ." +
"FILTER (?term NOT IN (?included)) . " +
"FILTER NOT EXISTS {?term a ?snapshot .} " +
"} ORDER BY " + orderSentence("?label"),
"} ORDER BY DESC(?hasLocaleLabel) lang(?label) " + orderSentence("?label") + "}",
TermDto.class);
query = setCommonFindAllRootsQueryParams(query, false);
try {
Expand Down Expand Up @@ -533,6 +539,8 @@ private void recursivelyLoadParentTermSubTerms(TermDto term) {
* <p>
* This method basically does a transitive closure of the vocabulary import relationship and retrieves a page of
* root terms from this closure.
* <p>
* Terms with a label in the instance language are prepended.
*
* @param vocabulary The last vocabulary in the vocabulary import chain
* @param pageSpec Page specification
Expand All @@ -544,13 +552,14 @@ public List<TermDto> findAllRootsIncludingImports(Vocabulary vocabulary, Pageabl
Objects.requireNonNull(vocabulary);
Objects.requireNonNull(pageSpec);
TypedQuery<TermDto> query = em.createNativeQuery("SELECT DISTINCT ?term WHERE {" +
"SELECT DISTINCT ?term ?hasLocaleLabel WHERE {" +
"?term a ?type ;" +
"?hasLabel ?label ." +
"?vocabulary ?imports* ?parent ." +
"?parent ?hasGlossary/?hasTerm ?term ." +
"FILTER (lang(?label) = ?labelLang) ." +
"BIND((lang(?label) = ?labelLang) as ?hasLocaleLabel) ." +
"FILTER (?term NOT IN (?included))" +
"} ORDER BY " + orderSentence("?label"),
"} ORDER BY DESC(?hasLocaleLabel) lang(?label) " + orderSentence("?label") + "}",
TermDto.class);
query = setCommonFindAllRootsQueryParams(query, true);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ public List<TermDto> findAllRoots(Vocabulary vocabulary, Pageable pageSpec, Coll
* Retrieves root terms (terms without parent).
* <p>
* The page specification parameter allows configuration of the number of results and their offset.
* <p>
* Terms with a label in the instance language are prepended.
*
* @param pageSpec Paging specification
* @param includeTerms Identifiers of terms which should be a part of the result. Optional
Expand All @@ -191,6 +193,8 @@ public List<TermDto> findAllRoots(Pageable pageSpec, Collection<URI> includeTerm
* <p>
* Basically, this does a transitive closure over the vocabulary import relationship, starting at the specified
* vocabulary, and returns all parent-less terms.
* <p>
* Terms with a label in the instance language are prepended.
*
* @param vocabulary Base vocabulary for the vocabulary import closure
* @param pageSpec Page specifying result number and position
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ public List<TermDto> findAllIncludingImported(Vocabulary vocabulary) {

/**
* Finds all root terms (terms without parent term) in the specified vocabulary.
* <p>
* Terms with a label in the instance language are prepended.
*
* @param vocabulary Vocabulary whose terms should be returned
* @param pageSpec Page specifying result number and position
Expand All @@ -255,6 +257,8 @@ public List<TermDto> findAllRoots(Vocabulary vocabulary, Pageable pageSpec,

/**
* Finds all root terms (terms without parent term).
* <p>
* Terms with a label in the instance language are prepended.
*
* @param pageSpec Page specifying result number and position
* @param includeTerms Identifiers of terms which should be a part of the result. Optional
Expand All @@ -273,6 +277,8 @@ public List<TermDto> findAllRoots(Pageable pageSpec,
* <p>
* Basically, this does a transitive closure over the vocabulary import relationship, starting at the specified
* vocabulary, and returns all parent-less terms.
* <p>
* Terms with a label in the instance language are prepended.
*
* @param vocabulary Base vocabulary for the vocabulary import closure
* @param pageSpec Page specifying result number and position
Expand Down
44 changes: 44 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 @@ -743,6 +743,50 @@ void findAllRootsOrdersResultsInLexicographicOrderForCzech() {
.collect(Collectors.toList()));
}

@Test
void findAllRootsReturnsTermsThatAreMissingDefaultLanguageLabel() {
configuration.getPersistence().setLanguage("cs");
// these terms will be missing Czech labels
persistTerms("en", "Germany", "China", "Spain", "Syria");
final List<TermDto> result = sut.findAllRoots(vocabulary, Constants.DEFAULT_PAGE_SPEC, Collections.emptyList());
assertEquals(4, result.size());
assertEquals(Arrays
.asList("China", "Germany", "Spain", "Syria"),
result.stream().map(r -> r.getLabel().get("en"))
.toList());
}

/**
* terms should be ordered - by language and then lexicographically, with the default language always first
*/
@Test
void findAllRootsReturnsTermsInMultipleLanguagesWithoutPrimaryLabelInCorrectOrder() {
configuration.getPersistence().setLanguage("cs");
persistTerms("cs", "Německo", "Čína");
persistTerms("af", "Duitsland", "Sjina");
persistTerms("en", "Germany", "China");
persistTerms("pl", "Niemcy", "Chiny");
persistTerms("da", "Tyskland", "Kina");
// lang order is: af, cs, da, en, pl
final List<TermDto> result = sut.findAllRoots(vocabulary, Constants.DEFAULT_PAGE_SPEC, Collections.emptyList());

// map results to another language than English if possible
final List<String> labels = result.stream().map(r -> {
final Optional<String> lang = r.getLabel().getLanguages().stream().filter(l -> !l.equals("en")).findAny();
return r.getLabel().get(lang.orElse("en"));
}).toList();

final List<String> expectedOrder = Arrays.asList(
"Čína", "Německo", // Czech as first, its default language
"Duitsland", "Sjina",
"Kina", "Tyskland",
"China", "Germany",
"Chiny", "Niemcy");

assertEquals(10, result.size());
assertEquals(expectedOrder, labels);
}

private void persistTerms(String lang, String... labels) {
transactional(() -> Arrays.stream(labels).forEach(label -> {
final Term parent = Generator.generateTermWithId();
Expand Down